github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/api/cloudcontroller/ccv3/task_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" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/ghttp" 13 ) 14 15 var _ = Describe("Task", func() { 16 var client *Client 17 18 BeforeEach(func() { 19 client, _ = NewTestClient() 20 }) 21 22 Describe("CreateApplicationTask", func() { 23 var ( 24 submitTask Task 25 26 task Task 27 warnings Warnings 28 executeErr error 29 ) 30 31 JustBeforeEach(func() { 32 task, warnings, executeErr = client.CreateApplicationTask("some-app-guid", submitTask) 33 }) 34 35 When("the application exists", func() { 36 var response string 37 38 BeforeEach(func() { 39 response = `{ 40 "sequence_id": 3 41 }` 42 }) 43 44 When("the name is empty", func() { 45 BeforeEach(func() { 46 server.AppendHandlers( 47 CombineHandlers( 48 VerifyRequest(http.MethodPost, "/v3/apps/some-app-guid/tasks"), 49 VerifyJSON(`{"command":"some command"}`), 50 RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}), 51 ), 52 ) 53 54 submitTask = Task{Command: "some command"} 55 }) 56 57 It("creates and returns the task and all warnings", func() { 58 Expect(executeErr).ToNot(HaveOccurred()) 59 60 Expect(task).To(Equal(Task{SequenceID: 3})) 61 Expect(warnings).To(ConsistOf("warning")) 62 }) 63 }) 64 65 When("the name is not empty", func() { 66 BeforeEach(func() { 67 server.AppendHandlers( 68 CombineHandlers( 69 VerifyRequest(http.MethodPost, "/v3/apps/some-app-guid/tasks"), 70 VerifyJSON(`{"command":"some command", "name":"some-task-name"}`), 71 RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}), 72 ), 73 ) 74 75 submitTask = Task{Command: "some command", Name: "some-task-name"} 76 }) 77 78 It("creates and returns the task and all warnings", func() { 79 Expect(executeErr).ToNot(HaveOccurred()) 80 81 Expect(task).To(Equal(Task{SequenceID: 3})) 82 Expect(warnings).To(ConsistOf("warning")) 83 }) 84 }) 85 86 When("the disk size is not 0", func() { 87 BeforeEach(func() { 88 response := `{ 89 "disk_in_mb": 123, 90 "sequence_id": 3 91 }` 92 server.AppendHandlers( 93 CombineHandlers( 94 VerifyRequest(http.MethodPost, "/v3/apps/some-app-guid/tasks"), 95 VerifyJSON(`{"command":"some command", "disk_in_mb": 123}`), 96 RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}), 97 ), 98 ) 99 submitTask = Task{Command: "some command", DiskInMB: uint64(123)} 100 }) 101 102 It("creates and returns the task and all warnings with the provided disk size", func() { 103 Expect(executeErr).ToNot(HaveOccurred()) 104 105 Expect(task).To(Equal(Task{DiskInMB: uint64(123), SequenceID: 3})) 106 Expect(warnings).To(ConsistOf("warning")) 107 }) 108 }) 109 110 When("the memory is not 0", func() { 111 BeforeEach(func() { 112 response := `{ 113 "memory_in_mb": 123, 114 "sequence_id": 3 115 }` 116 server.AppendHandlers( 117 CombineHandlers( 118 VerifyRequest(http.MethodPost, "/v3/apps/some-app-guid/tasks"), 119 VerifyJSON(`{"command":"some command", "memory_in_mb": 123}`), 120 RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}), 121 ), 122 ) 123 124 submitTask = Task{Command: "some command", MemoryInMB: uint64(123)} 125 }) 126 127 It("creates and returns the task and all warnings with the provided memory", func() { 128 Expect(executeErr).ToNot(HaveOccurred()) 129 130 Expect(task).To(Equal(Task{MemoryInMB: uint64(123), SequenceID: 3})) 131 Expect(warnings).To(ConsistOf("warning")) 132 }) 133 }) 134 135 }) 136 137 When("the cloud controller returns errors and warnings", func() { 138 BeforeEach(func() { 139 response := `{ 140 "errors": [ 141 { 142 "code": 10008, 143 "detail": "The request is semantically invalid: command presence", 144 "title": "CF-UnprocessableEntity" 145 }, 146 { 147 "code": 10010, 148 "detail": "App not found", 149 "title": "CF-ResourceNotFound" 150 } 151 ] 152 }` 153 server.AppendHandlers( 154 CombineHandlers( 155 VerifyRequest(http.MethodPost, "/v3/apps/some-app-guid/tasks"), 156 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning"}}), 157 ), 158 ) 159 160 submitTask = Task{Command: "some command"} 161 }) 162 163 It("returns the errors and all warnings", func() { 164 Expect(executeErr).To(MatchError(ccerror.MultiError{ 165 ResponseCode: http.StatusTeapot, 166 Errors: []ccerror.V3Error{ 167 { 168 Code: 10008, 169 Detail: "The request is semantically invalid: command presence", 170 Title: "CF-UnprocessableEntity", 171 }, 172 { 173 Code: 10010, 174 Detail: "App not found", 175 Title: "CF-ResourceNotFound", 176 }, 177 }, 178 })) 179 Expect(warnings).To(ConsistOf("warning")) 180 }) 181 }) 182 }) 183 184 Describe("GetApplicationTasks", func() { 185 var ( 186 submitQuery Query 187 188 tasks []Task 189 warnings Warnings 190 executeErr error 191 ) 192 193 JustBeforeEach(func() { 194 tasks, warnings, executeErr = client.GetApplicationTasks("some-app-guid", submitQuery) 195 }) 196 197 When("the application exists", func() { 198 BeforeEach(func() { 199 response1 := fmt.Sprintf(`{ 200 "pagination": { 201 "next": { 202 "href": "%s/v3/apps/some-app-guid/tasks?per_page=2&page=2" 203 } 204 }, 205 "resources": [ 206 { 207 "guid": "task-1-guid", 208 "sequence_id": 1, 209 "name": "task-1", 210 "command": "some-command", 211 "state": "SUCCEEDED", 212 "created_at": "2016-11-07T05:59:01Z" 213 }, 214 { 215 "guid": "task-2-guid", 216 "sequence_id": 2, 217 "name": "task-2", 218 "command": "some-command", 219 "state": "FAILED", 220 "created_at": "2016-11-07T06:59:01Z" 221 } 222 ] 223 }`, server.URL()) 224 response2 := `{ 225 "pagination": { 226 "next": null 227 }, 228 "resources": [ 229 { 230 "guid": "task-3-guid", 231 "sequence_id": 3, 232 "name": "task-3", 233 "command": "some-command", 234 "state": "RUNNING", 235 "created_at": "2016-11-07T07:59:01Z" 236 } 237 ] 238 }` 239 server.AppendHandlers( 240 CombineHandlers( 241 VerifyRequest(http.MethodGet, "/v3/apps/some-app-guid/tasks", "per_page=2"), 242 RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"warning-1"}}), 243 ), 244 ) 245 server.AppendHandlers( 246 CombineHandlers( 247 VerifyRequest(http.MethodGet, "/v3/apps/some-app-guid/tasks", "per_page=2&page=2"), 248 RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"warning-2"}}), 249 ), 250 ) 251 252 submitQuery = Query{Key: PerPage, Values: []string{"2"}} 253 }) 254 255 It("returns a list of tasks associated with the application and all warnings", func() { 256 Expect(executeErr).ToNot(HaveOccurred()) 257 258 Expect(tasks).To(ConsistOf( 259 Task{ 260 GUID: "task-1-guid", 261 SequenceID: 1, 262 Name: "task-1", 263 State: constant.TaskSucceeded, 264 CreatedAt: "2016-11-07T05:59:01Z", 265 Command: "some-command", 266 }, 267 Task{ 268 GUID: "task-2-guid", 269 SequenceID: 2, 270 Name: "task-2", 271 State: constant.TaskFailed, 272 CreatedAt: "2016-11-07T06:59:01Z", 273 Command: "some-command", 274 }, 275 Task{ 276 GUID: "task-3-guid", 277 SequenceID: 3, 278 Name: "task-3", 279 State: constant.TaskRunning, 280 CreatedAt: "2016-11-07T07:59:01Z", 281 Command: "some-command", 282 }, 283 )) 284 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 285 }) 286 }) 287 288 When("the application does not exist", func() { 289 BeforeEach(func() { 290 response := `{ 291 "errors": [ 292 { 293 "code": 10010, 294 "detail": "App not found", 295 "title": "CF-ResourceNotFound" 296 } 297 ] 298 }` 299 server.AppendHandlers( 300 CombineHandlers( 301 VerifyRequest(http.MethodGet, "/v3/apps/some-app-guid/tasks"), 302 RespondWith(http.StatusNotFound, response), 303 ), 304 ) 305 }) 306 307 It("returns a ResourceNotFoundError", func() { 308 Expect(executeErr).To(MatchError(ccerror.ApplicationNotFoundError{})) 309 }) 310 }) 311 312 When("the cloud controller returns errors and warnings", func() { 313 BeforeEach(func() { 314 response := `{ 315 "errors": [ 316 { 317 "code": 10008, 318 "detail": "The request is semantically invalid: command presence", 319 "title": "CF-UnprocessableEntity" 320 }, 321 { 322 "code": 10010, 323 "detail": "App not found", 324 "title": "CF-ResourceNotFound" 325 } 326 ] 327 }` 328 server.AppendHandlers( 329 CombineHandlers( 330 VerifyRequest(http.MethodGet, "/v3/apps/some-app-guid/tasks"), 331 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning"}}), 332 ), 333 ) 334 }) 335 336 It("returns the errors and all warnings", func() { 337 Expect(executeErr).To(MatchError(ccerror.MultiError{ 338 ResponseCode: http.StatusTeapot, 339 Errors: []ccerror.V3Error{ 340 { 341 Code: 10008, 342 Detail: "The request is semantically invalid: command presence", 343 Title: "CF-UnprocessableEntity", 344 }, 345 { 346 Code: 10010, 347 Detail: "App not found", 348 Title: "CF-ResourceNotFound", 349 }, 350 }, 351 })) 352 Expect(warnings).To(ConsistOf("warning")) 353 }) 354 }) 355 }) 356 357 Describe("UpdateTaskCancel", func() { 358 var ( 359 task Task 360 warnings Warnings 361 executeErr error 362 ) 363 364 JustBeforeEach(func() { 365 task, warnings, executeErr = client.UpdateTaskCancel("some-task-guid") 366 }) 367 368 When("the request succeeds", func() { 369 BeforeEach(func() { 370 response := `{ 371 "guid": "task-3-guid", 372 "sequence_id": 3, 373 "name": "task-3", 374 "command": "some-command", 375 "state": "CANCELING", 376 "created_at": "2016-11-07T07:59:01Z" 377 }` 378 server.AppendHandlers( 379 CombineHandlers( 380 VerifyRequest(http.MethodPut, "/v3/tasks/some-task-guid/cancel"), 381 RespondWith(http.StatusAccepted, response, http.Header{"X-Cf-Warnings": {"warning"}}), 382 ), 383 ) 384 }) 385 386 It("returns the task and warnings", func() { 387 Expect(executeErr).ToNot(HaveOccurred()) 388 389 Expect(task).To(Equal(Task{ 390 GUID: "task-3-guid", 391 SequenceID: 3, 392 Name: "task-3", 393 Command: "some-command", 394 State: constant.TaskCanceling, 395 CreatedAt: "2016-11-07T07:59:01Z", 396 })) 397 Expect(warnings).To(ConsistOf("warning")) 398 }) 399 }) 400 401 When("the request fails", func() { 402 BeforeEach(func() { 403 response := `{ 404 "errors": [ 405 { 406 "code": 10008, 407 "detail": "The request is semantically invalid: command presence", 408 "title": "CF-UnprocessableEntity" 409 }, 410 { 411 "code": 10010, 412 "detail": "App not found", 413 "title": "CF-ResourceNotFound" 414 } 415 ] 416 }` 417 server.AppendHandlers( 418 CombineHandlers( 419 VerifyRequest(http.MethodPut, "/v3/tasks/some-task-guid/cancel"), 420 RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"warning"}}), 421 ), 422 ) 423 }) 424 425 It("returns the errors and all warnings", func() { 426 Expect(executeErr).To(MatchError(ccerror.MultiError{ 427 ResponseCode: http.StatusTeapot, 428 Errors: []ccerror.V3Error{ 429 { 430 Code: 10008, 431 Detail: "The request is semantically invalid: command presence", 432 Title: "CF-UnprocessableEntity", 433 }, 434 { 435 Code: 10010, 436 Detail: "App not found", 437 Title: "CF-ResourceNotFound", 438 }, 439 }, 440 })) 441 Expect(warnings).To(ConsistOf("warning")) 442 }) 443 }) 444 }) 445 })