github.com/orange-cloudfoundry/cli@v7.1.0+incompatible/api/cloudcontroller/ccv3/deployment_test.go (about)

     1  package ccv3_test
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
     9  
    10  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/ghttp"
    14  )
    15  
    16  var _ = Describe("Task", func() {
    17  	var client *Client
    18  
    19  	BeforeEach(func() {
    20  		client, _ = NewTestClient()
    21  	})
    22  
    23  	Describe("GetDeployments", func() {
    24  		var (
    25  			deployments []Deployment
    26  			warnings    Warnings
    27  			executeErr  error
    28  		)
    29  
    30  		JustBeforeEach(func() {
    31  			deployments, warnings, executeErr = client.GetDeployments(Query{Key: AppGUIDFilter, Values: []string{"some-app-guid"}}, Query{Key: OrderBy, Values: []string{"-created_at"}}, Query{Key: PerPage, Values: []string{"1"}})
    32  		})
    33  
    34  		var response string
    35  		var response2 string
    36  		BeforeEach(func() {
    37  			response = fmt.Sprintf(`{
    38  	"pagination": {
    39  		"next": {
    40  			"href": "%s/v3/deployments?app_guids=some-app-guid&order_by=-created_at&page=2&per_page=1"
    41  		}
    42  	},
    43  	"resources": [
    44  		{
    45        		"guid": "newest-deployment-guid",
    46        		"created_at": "2018-05-25T22:42:10Z"
    47     	}
    48  	]
    49  }`, server.URL())
    50  			response2 = `{
    51    	"pagination": {
    52  		"next": null
    53  	},
    54  	"resources": [
    55  		{
    56        		"guid": "oldest-deployment-guid",
    57        		"created_at": "2018-04-25T22:42:10Z"
    58     	}
    59  	]
    60  }`
    61  		})
    62  
    63  		Context("when the deployment exists", func() {
    64  			BeforeEach(func() {
    65  				server.AppendHandlers(
    66  					CombineHandlers(
    67  						VerifyRequest(http.MethodGet, "/v3/deployments", "app_guids=some-app-guid&order_by=-created_at&per_page=1"),
    68  						RespondWith(http.StatusAccepted, response),
    69  					),
    70  				)
    71  
    72  				server.AppendHandlers(
    73  					CombineHandlers(
    74  						VerifyRequest(http.MethodGet, "/v3/deployments", "app_guids=some-app-guid&order_by=-created_at&page=2&per_page=1"),
    75  						RespondWith(http.StatusAccepted, response2, http.Header{"X-Cf-Warnings": {"warning"}}),
    76  					),
    77  				)
    78  
    79  			})
    80  
    81  			It("returns the deployment guid of the most recent deployment", func() {
    82  				Expect(executeErr).ToNot(HaveOccurred())
    83  				Expect(warnings).To(ConsistOf("warning"))
    84  				Expect(deployments).To(ConsistOf(
    85  					Deployment{GUID: "newest-deployment-guid", CreatedAt: "2018-05-25T22:42:10Z"},
    86  					Deployment{GUID: "oldest-deployment-guid", CreatedAt: "2018-04-25T22:42:10Z"},
    87  				))
    88  			})
    89  
    90  		})
    91  
    92  		Context("when the request fails", func() {
    93  			BeforeEach(func() {
    94  				response := `{
    95    "errors": [
    96      {
    97        "code": 10008,
    98        "detail": "The request is semantically invalid: command presence",
    99        "title": "CF-UnprocessableEntity"
   100      },
   101      {
   102        "code": 10010,
   103        "detail": "App not found",
   104        "title": "CF-ResourceNotFound"
   105      }
   106    ]
   107  }`
   108  
   109  				server.AppendHandlers(
   110  					CombineHandlers(
   111  						VerifyRequest(http.MethodGet, "/v3/deployments", "app_guids=some-app-guid&order_by=-created_at&per_page=1"),
   112  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning"}}),
   113  					),
   114  				)
   115  			})
   116  
   117  			It("returns CC warnings and error", func() {
   118  				Expect(executeErr).To(MatchError(ccerror.MultiError{
   119  					ResponseCode: http.StatusTeapot,
   120  					Errors: []ccerror.V3Error{
   121  						{
   122  							Code:   10008,
   123  							Detail: "The request is semantically invalid: command presence",
   124  							Title:  "CF-UnprocessableEntity",
   125  						},
   126  						{
   127  							Code:   10010,
   128  							Detail: "App not found",
   129  							Title:  "CF-ResourceNotFound",
   130  						},
   131  					},
   132  				}))
   133  				Expect(warnings).To(ConsistOf("warning"))
   134  			})
   135  		})
   136  	})
   137  
   138  	Describe("CancelDeployment", func() {
   139  		var (
   140  			warnings   Warnings
   141  			executeErr error
   142  		)
   143  
   144  		JustBeforeEach(func() {
   145  			warnings, executeErr = client.CancelDeployment("some-deployment-guid")
   146  		})
   147  
   148  		Context("when the deployment exists", func() {
   149  			Context("when cancelling the deployment succeeds", func() {
   150  				BeforeEach(func() {
   151  					server.AppendHandlers(
   152  						CombineHandlers(
   153  							VerifyRequest(http.MethodPost, "/v3/deployments/some-deployment-guid/actions/cancel"),
   154  							RespondWith(http.StatusAccepted, "", http.Header{"X-Cf-Warnings": {"warning"}}),
   155  						),
   156  					)
   157  				})
   158  
   159  				It("cancels the deployment with no errors and returns all warnings", func() {
   160  					Expect(executeErr).ToNot(HaveOccurred())
   161  					Expect(warnings).To(ConsistOf("warning"))
   162  				})
   163  			})
   164  		})
   165  	})
   166  
   167  	Describe("CreateApplicationDeployment", func() {
   168  		var (
   169  			deploymentGUID string
   170  			warnings       Warnings
   171  			executeErr     error
   172  			dropletGUID    string
   173  		)
   174  
   175  		JustBeforeEach(func() {
   176  			deploymentGUID, warnings, executeErr = client.CreateApplicationDeployment("some-app-guid", dropletGUID)
   177  		})
   178  
   179  		Context("when the application exists", func() {
   180  			var response string
   181  			BeforeEach(func() {
   182  				dropletGUID = "some-droplet-guid"
   183  				response = `{
   184    "guid": "some-deployment-guid",
   185    "created_at": "2018-04-25T22:42:10Z",
   186    "relationships": {
   187      "app": {
   188        "data": {
   189          "guid": "some-app-guid"
   190        }
   191      }
   192    }
   193  }`
   194  			})
   195  
   196  			Context("when creating the deployment succeeds", func() {
   197  				BeforeEach(func() {
   198  					server.AppendHandlers(
   199  						CombineHandlers(
   200  							VerifyRequest(http.MethodPost, "/v3/deployments"),
   201  							VerifyJSON(`{"droplet":{ "guid":"some-droplet-guid" }, "relationships":{"app":{"data":{"guid":"some-app-guid"}}}}`),
   202  							RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}),
   203  						),
   204  					)
   205  				})
   206  
   207  				It("creates the deployment with no errors and returns all warnings", func() {
   208  					Expect(deploymentGUID).To(Equal("some-deployment-guid"))
   209  					Expect(executeErr).ToNot(HaveOccurred())
   210  					Expect(warnings).To(ConsistOf("warning"))
   211  				})
   212  
   213  			})
   214  
   215  			Context("when no droplet guid is provided", func() {
   216  				BeforeEach(func() {
   217  					dropletGUID = ""
   218  					server.AppendHandlers(
   219  						CombineHandlers(
   220  							VerifyRequest(http.MethodPost, "/v3/deployments"),
   221  							VerifyJSON(`{"relationships":{"app":{"data":{"guid":"some-app-guid"}}}}`),
   222  							RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}),
   223  						),
   224  					)
   225  				})
   226  
   227  				It("omits the droplet object in the JSON", func() {
   228  					Expect(executeErr).ToNot(HaveOccurred())
   229  					Expect(warnings).To(ConsistOf("warning"))
   230  				})
   231  			})
   232  		})
   233  	})
   234  
   235  	Describe("CreateApplicationDeploymentByRevision", func() {
   236  		var (
   237  			deploymentGUID string
   238  			warnings       Warnings
   239  			executeErr     error
   240  			revisionGUID   string
   241  		)
   242  
   243  		JustBeforeEach(func() {
   244  			deploymentGUID, warnings, executeErr = client.CreateApplicationDeploymentByRevision("some-app-guid", revisionGUID)
   245  		})
   246  
   247  		Context("when the application exists", func() {
   248  			var response string
   249  			BeforeEach(func() {
   250  				revisionGUID = "some-revision-guid"
   251  				response = `{
   252    "guid": "some-deployment-guid",
   253    "created_at": "2018-04-25T22:42:10Z",
   254    "relationships": {
   255      "app": {
   256        "data": {
   257          "guid": "some-app-guid"
   258        }
   259      }
   260    }
   261  }`
   262  			})
   263  
   264  			Context("when creating the deployment succeeds", func() {
   265  				BeforeEach(func() {
   266  					server.AppendHandlers(
   267  						CombineHandlers(
   268  							VerifyRequest(http.MethodPost, "/v3/deployments"),
   269  							VerifyJSON(`{"revision":{ "guid":"some-revision-guid" }, "relationships":{"app":{"data":{"guid":"some-app-guid"}}}}`),
   270  							RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}),
   271  						),
   272  					)
   273  				})
   274  
   275  				It("creates the deployment with no errors and returns all warnings", func() {
   276  					Expect(deploymentGUID).To(Equal("some-deployment-guid"))
   277  					Expect(executeErr).ToNot(HaveOccurred())
   278  					Expect(warnings).To(ConsistOf("warning"))
   279  				})
   280  			})
   281  		})
   282  	})
   283  
   284  	Describe("GetDeployment", func() {
   285  		var response string
   286  		Context("When the deployments exists", func() {
   287  			BeforeEach(func() {
   288  				response = `{
   289  				    "guid": "some-deployment-guid",
   290  					"state": "DEPLOYED",
   291  					"status": {
   292  						"value": "FINALIZED",
   293  						"reason": "SUPERSEDED"
   294  					},
   295  					"droplet": {
   296   					  "guid": "some-droplet-guid"
   297  					},
   298   					"previous_droplet": {
   299   					  "guid": "some-other-droplet-guid"
   300   					},
   301   					"created_at": "some-time",
   302   					"updated_at": "some-later-time",
   303   					"relationships": {
   304   					  "app": {
   305   					    "data": {
   306   					      "guid": "some-app-guid"
   307   					    }
   308   					  }
   309   					}
   310  				}`
   311  				server.AppendHandlers(
   312  					CombineHandlers(
   313  						VerifyRequest(http.MethodGet, "/v3/deployments/some-deployment-guid"),
   314  						RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}),
   315  					),
   316  				)
   317  			})
   318  			It("Successfully returns a deployment object", func() {
   319  				deployment, warnings, err := client.GetDeployment("some-deployment-guid")
   320  				Expect(err).ToNot(HaveOccurred())
   321  				Expect(warnings).To(ConsistOf("warning"))
   322  				Expect(deployment).To(Not(BeNil()))
   323  				Expect(deployment.GUID).To(Equal("some-deployment-guid"))
   324  				Expect(deployment.State).To(Equal(constant.DeploymentDeployed))
   325  				Expect(deployment.StatusValue).To(Equal(constant.DeploymentStatusValueFinalized))
   326  				Expect(deployment.StatusReason).To(Equal(constant.DeploymentStatusReasonSuperseded))
   327  			})
   328  		})
   329  
   330  		Context("when the deployment doesn't exist", func() {
   331  			BeforeEach(func() {
   332  				response := `{
   333  					"errors": [
   334  						{
   335  							"code": 10010,
   336  							"detail": "Deployment not found",
   337  							"title": "CF-ResourceNotFound"
   338  						}
   339  					]
   340  				}`
   341  				server.AppendHandlers(
   342  					CombineHandlers(
   343  						VerifyRequest(http.MethodGet, "/v3/deployments/not-a-deployment"),
   344  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"warning-deployment"}}),
   345  					),
   346  				)
   347  			})
   348  
   349  			It("returns the error", func() {
   350  				_, warnings, err := client.GetDeployment("not-a-deployment")
   351  				Expect(err).To(MatchError(ccerror.DeploymentNotFoundError{}))
   352  				Expect(warnings).To(ConsistOf("warning-deployment"))
   353  			})
   354  		})
   355  	})
   356  })