github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/actor/v2action/route_test.go (about) 1 package v2action_test 2 3 import ( 4 "errors" 5 "fmt" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 . "code.cloudfoundry.org/cli/actor/v2action" 9 "code.cloudfoundry.org/cli/actor/v2action/v2actionfakes" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 13 "code.cloudfoundry.org/cli/types" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/ginkgo/extensions/table" 16 . "github.com/onsi/gomega" 17 ) 18 19 var _ = Describe("Route Actions", func() { 20 var ( 21 actor *Actor 22 fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient 23 ) 24 25 BeforeEach(func() { 26 fakeCloudControllerClient = new(v2actionfakes.FakeCloudControllerClient) 27 actor = NewActor(fakeCloudControllerClient, nil, nil) 28 }) 29 30 Describe("Route", func() { 31 DescribeTable("String", 32 func(host string, domain string, path string, port types.NullInt, expectedValue string) { 33 route := Route{ 34 Host: host, 35 Domain: Domain{ 36 Name: domain, 37 }, 38 Path: path, 39 Port: port, 40 } 41 Expect(route.String()).To(Equal(expectedValue)) 42 }, 43 44 Entry("has domain", "", "domain.com", "", types.NullInt{IsSet: false}, "domain.com"), 45 Entry("has host, domain", "host", "domain.com", "", types.NullInt{IsSet: false}, "host.domain.com"), 46 Entry("has domain, path", "", "domain.com", "/path", types.NullInt{IsSet: false}, "domain.com/path"), 47 Entry("has domain, path", "", "domain.com", "path", types.NullInt{IsSet: false}, "domain.com/path"), 48 Entry("has host, domain, path", "host", "domain.com", "/path", types.NullInt{IsSet: false}, "host.domain.com/path"), 49 Entry("has domain, port", "", "domain.com", "", types.NullInt{IsSet: true, Value: 3333}, "domain.com:3333"), 50 Entry("has host, domain, path, port", "host", "domain.com", "/path", types.NullInt{IsSet: true, Value: 3333}, "host.domain.com:3333/path"), 51 ) 52 53 Describe("RandomTCPPort", func() { 54 var ( 55 route Route 56 domain Domain 57 port types.NullInt 58 ) 59 60 JustBeforeEach(func() { 61 route = Route{ 62 Domain: domain, 63 Port: port, 64 } 65 }) 66 67 When("the domain is a tcp domain and there is no port specified", func() { 68 BeforeEach(func() { 69 domain = Domain{ 70 RouterGroupType: constant.TCPRouterGroup, 71 } 72 port = types.NullInt{} 73 }) 74 75 It("returns true", func() { 76 Expect(route.RandomTCPPort()).To(BeTrue()) 77 }) 78 }) 79 80 When("the domain is a tcp domain and the port is specified", func() { 81 BeforeEach(func() { 82 domain = Domain{ 83 RouterGroupType: constant.TCPRouterGroup, 84 } 85 port = types.NullInt{IsSet: true} 86 }) 87 88 It("returns false", func() { 89 Expect(route.RandomTCPPort()).To(BeFalse()) 90 }) 91 }) 92 93 When("the domain is a not tcp domain", func() { 94 BeforeEach(func() { 95 domain = Domain{} 96 port = types.NullInt{} 97 }) 98 99 It("returns false", func() { 100 Expect(route.RandomTCPPort()).To(BeFalse()) 101 }) 102 }) 103 }) 104 105 DescribeTable("Validate", 106 func(route Route, expectedErr error) { 107 err := route.Validate() 108 if expectedErr == nil { 109 Expect(err).To(BeNil()) 110 } else { 111 Expect(err).To(Equal(expectedErr)) 112 } 113 }, 114 115 Entry("valid - host and path on HTTP domain", 116 Route{ 117 Host: "some-host", 118 Path: "some-path", 119 Domain: Domain{ 120 Name: "some-domain", 121 }, 122 }, 123 nil, 124 ), 125 126 Entry("valid - port on TCP domain", 127 Route{ 128 Port: types.NullInt{IsSet: true}, 129 Domain: Domain{ 130 Name: "some-domain", 131 RouterGroupType: constant.TCPRouterGroup, 132 }, 133 }, 134 nil, 135 ), 136 137 Entry("error - no host on shared HTTP domain", 138 Route{ 139 Path: "some-path", 140 Domain: Domain{ 141 Name: "some-domain", 142 Type: constant.SharedDomain, 143 }, 144 }, 145 actionerror.NoHostnameAndSharedDomainError{}, 146 ), 147 148 Entry("error - port on HTTP domain", 149 Route{ 150 Port: types.NullInt{IsSet: true}, 151 Domain: Domain{ 152 Name: "some-domain", 153 }, 154 }, 155 actionerror.InvalidHTTPRouteSettings{Domain: "some-domain"}, 156 ), 157 158 Entry("error - hostname on TCP domain", 159 Route{ 160 Host: "some-host", 161 Domain: Domain{ 162 Name: "some-domain", 163 RouterGroupType: constant.TCPRouterGroup, 164 }, 165 }, 166 actionerror.InvalidTCPRouteSettings{Domain: "some-domain"}, 167 ), 168 169 Entry("error - path on TCP domain", 170 Route{ 171 Path: "some-path", 172 Domain: Domain{ 173 Name: "some-domain", 174 RouterGroupType: constant.TCPRouterGroup, 175 }, 176 }, 177 actionerror.InvalidTCPRouteSettings{Domain: "some-domain"}, 178 ), 179 ) 180 181 DescribeTable("ValidateWithRandomPort", 182 func(route Route, randomPort bool, expectedErr error) { 183 err := route.ValidateWithRandomPort(randomPort) 184 if expectedErr == nil { 185 Expect(err).To(BeNil()) 186 } else { 187 Expect(err).To(Equal(expectedErr)) 188 } 189 }, 190 191 Entry("valid - host and path on HTTP domain", 192 Route{ 193 Host: "some-host", 194 Path: "some-path", 195 Domain: Domain{ 196 Name: "some-domain", 197 }, 198 }, 199 false, 200 nil, 201 ), 202 203 Entry("valid - port on TCP domain", 204 Route{ 205 Port: types.NullInt{IsSet: true}, 206 Domain: Domain{ 207 Name: "some-domain", 208 RouterGroupType: constant.TCPRouterGroup, 209 }, 210 }, 211 false, 212 nil, 213 ), 214 215 Entry("error - port on HTTP domain", 216 Route{ 217 Port: types.NullInt{IsSet: true}, 218 Domain: Domain{ 219 Name: "some-domain", 220 }, 221 }, 222 false, 223 actionerror.InvalidHTTPRouteSettings{Domain: "some-domain"}, 224 ), 225 226 Entry("error - randomport on HTTP domain", 227 Route{ 228 Port: types.NullInt{IsSet: false}, 229 Domain: Domain{ 230 Name: "some-domain", 231 }, 232 }, 233 true, 234 actionerror.InvalidHTTPRouteSettings{Domain: "some-domain"}, 235 ), 236 237 Entry("error - hostname on TCP domain", 238 Route{ 239 Host: "some-host", 240 Domain: Domain{ 241 Name: "some-domain", 242 RouterGroupType: constant.TCPRouterGroup, 243 }, 244 }, 245 true, 246 actionerror.InvalidTCPRouteSettings{Domain: "some-domain"}, 247 ), 248 249 Entry("error - path on TCP domain", 250 Route{ 251 Path: "some-path", 252 Domain: Domain{ 253 Name: "some-domain", 254 RouterGroupType: constant.TCPRouterGroup, 255 }, 256 }, 257 true, 258 actionerror.InvalidTCPRouteSettings{Domain: "some-domain"}, 259 ), 260 ) 261 }) 262 263 Describe("MapRouteToApplication", func() { 264 When("no errors are encountered", func() { 265 BeforeEach(func() { 266 fakeCloudControllerClient.UpdateRouteApplicationReturns( 267 ccv2.Route{}, 268 ccv2.Warnings{"map warning"}, 269 nil) 270 }) 271 272 It("maps the route to the application and returns all warnings", func() { 273 warnings, err := actor.MapRouteToApplication("some-route-guid", "some-app-guid") 274 Expect(err).ToNot(HaveOccurred()) 275 Expect(warnings).To(ConsistOf("map warning")) 276 277 Expect(fakeCloudControllerClient.UpdateRouteApplicationCallCount()).To(Equal(1)) 278 routeGUID, appGUID := fakeCloudControllerClient.UpdateRouteApplicationArgsForCall(0) 279 Expect(routeGUID).To(Equal("some-route-guid")) 280 Expect(appGUID).To(Equal("some-app-guid")) 281 }) 282 }) 283 284 When("an error is encountered", func() { 285 Context("InvalidRelationError", func() { 286 BeforeEach(func() { 287 fakeCloudControllerClient.UpdateRouteApplicationReturns( 288 ccv2.Route{}, 289 ccv2.Warnings{"map warning"}, 290 ccerror.InvalidRelationError{}) 291 }) 292 293 It("returns the error", func() { 294 warnings, err := actor.MapRouteToApplication("some-route-guid", "some-app-guid") 295 Expect(err).To(MatchError(actionerror.RouteInDifferentSpaceError{})) 296 Expect(warnings).To(ConsistOf("map warning")) 297 }) 298 }) 299 300 Context("generic error", func() { 301 var expectedErr error 302 303 BeforeEach(func() { 304 expectedErr = errors.New("map route failed") 305 fakeCloudControllerClient.UpdateRouteApplicationReturns( 306 ccv2.Route{}, 307 ccv2.Warnings{"map warning"}, 308 expectedErr) 309 }) 310 311 It("returns the error", func() { 312 warnings, err := actor.MapRouteToApplication("some-route-guid", "some-app-guid") 313 Expect(err).To(MatchError(expectedErr)) 314 Expect(warnings).To(ConsistOf("map warning")) 315 }) 316 }) 317 }) 318 }) 319 320 Describe("UnmapRouteFromApplication", func() { 321 When("no errors are encountered", func() { 322 BeforeEach(func() { 323 fakeCloudControllerClient.DeleteRouteApplicationReturns( 324 ccv2.Warnings{"map warning"}, 325 nil) 326 }) 327 328 It("unmaps the route from the application and returns all warnings", func() { 329 warnings, err := actor.UnmapRouteFromApplication("some-route-guid", "some-app-guid") 330 Expect(err).ToNot(HaveOccurred()) 331 Expect(warnings).To(ConsistOf("map warning")) 332 333 Expect(fakeCloudControllerClient.DeleteRouteApplicationCallCount()).To(Equal(1)) 334 routeGUID, appGUID := fakeCloudControllerClient.DeleteRouteApplicationArgsForCall(0) 335 Expect(routeGUID).To(Equal("some-route-guid")) 336 Expect(appGUID).To(Equal("some-app-guid")) 337 }) 338 }) 339 340 When("an error is encountered", func() { 341 var expectedErr error 342 343 BeforeEach(func() { 344 expectedErr = errors.New("map route failed") 345 fakeCloudControllerClient.DeleteRouteApplicationReturns( 346 ccv2.Warnings{"map warning"}, 347 expectedErr) 348 }) 349 350 It("returns the error", func() { 351 warnings, err := actor.UnmapRouteFromApplication("some-route-guid", "some-app-guid") 352 Expect(err).To(MatchError(expectedErr)) 353 Expect(warnings).To(ConsistOf("map warning")) 354 }) 355 }) 356 }) 357 358 Describe("CreateRoute", func() { 359 When("no errors are encountered", func() { 360 BeforeEach(func() { 361 fakeCloudControllerClient.CreateRouteReturns( 362 ccv2.Route{ 363 GUID: "some-route-guid", 364 Host: "some-host", 365 Path: "some-path", 366 Port: types.NullInt{IsSet: true, Value: 3333}, 367 DomainGUID: "some-domain-guid", 368 SpaceGUID: "some-space-guid", 369 }, 370 ccv2.Warnings{"create route warning"}, 371 nil) 372 }) 373 374 It("creates the route and returns all warnings", func() { 375 route, warnings, err := actor.CreateRoute(Route{ 376 Domain: Domain{ 377 Name: "some-domain", 378 GUID: "some-domain-guid", 379 }, 380 Host: "some-host", 381 Path: "/some-path", 382 Port: types.NullInt{IsSet: true, Value: 3333}, 383 SpaceGUID: "some-space-guid", 384 }, 385 true) 386 Expect(err).ToNot(HaveOccurred()) 387 Expect(warnings).To(ConsistOf("create route warning")) 388 Expect(route).To(Equal(Route{ 389 Domain: Domain{ 390 Name: "some-domain", 391 GUID: "some-domain-guid", 392 }, 393 GUID: "some-route-guid", 394 Host: "some-host", 395 Path: "some-path", 396 Port: types.NullInt{IsSet: true, Value: 3333}, 397 SpaceGUID: "some-space-guid", 398 })) 399 400 Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1)) 401 passedRoute, generatePort := fakeCloudControllerClient.CreateRouteArgsForCall(0) 402 Expect(passedRoute).To(Equal(ccv2.Route{ 403 DomainGUID: "some-domain-guid", 404 Host: "some-host", 405 Path: "/some-path", 406 Port: types.NullInt{IsSet: true, Value: 3333}, 407 SpaceGUID: "some-space-guid", 408 })) 409 Expect(generatePort).To(BeTrue()) 410 }) 411 }) 412 413 When("path does not start with /", func() { 414 It("prepends / to path", func() { 415 _, _, err := actor.CreateRoute( 416 Route{ 417 Domain: Domain{ 418 Name: "some-domain", 419 GUID: "some-domain-guid", 420 }, 421 Host: "some-host", 422 Path: "some-path", 423 Port: types.NullInt{IsSet: true, Value: 3333}, 424 SpaceGUID: "some-space-guid", 425 }, 426 true, 427 ) 428 Expect(err).ToNot(HaveOccurred()) 429 Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1)) 430 passedRoute, _ := fakeCloudControllerClient.CreateRouteArgsForCall(0) 431 Expect(passedRoute).To(Equal(ccv2.Route{ 432 DomainGUID: "some-domain-guid", 433 Host: "some-host", 434 Path: "/some-path", 435 Port: types.NullInt{IsSet: true, Value: 3333}, 436 SpaceGUID: "some-space-guid", 437 })) 438 }) 439 }) 440 441 When("is not provided", func() { 442 It("passes empty path", func() { 443 _, _, err := actor.CreateRoute( 444 Route{ 445 Domain: Domain{ 446 Name: "some-domain", 447 GUID: "some-domain-guid", 448 }, 449 Host: "some-host", 450 Port: types.NullInt{IsSet: true, Value: 3333}, 451 SpaceGUID: "some-space-guid", 452 }, 453 true, 454 ) 455 Expect(err).ToNot(HaveOccurred()) 456 Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1)) 457 passedRoute, _ := fakeCloudControllerClient.CreateRouteArgsForCall(0) 458 Expect(passedRoute).To(Equal(ccv2.Route{ 459 DomainGUID: "some-domain-guid", 460 Host: "some-host", 461 Port: types.NullInt{IsSet: true, Value: 3333}, 462 SpaceGUID: "some-space-guid", 463 })) 464 }) 465 }) 466 467 When("an error is encountered", func() { 468 var expectedErr error 469 470 BeforeEach(func() { 471 expectedErr = errors.New("map route failed") 472 fakeCloudControllerClient.CreateRouteReturns( 473 ccv2.Route{}, 474 ccv2.Warnings{"create route warning"}, 475 expectedErr) 476 }) 477 478 It("returns the error", func() { 479 _, warnings, err := actor.CreateRoute(Route{}, true) 480 Expect(err).To(MatchError(expectedErr)) 481 Expect(warnings).To(ConsistOf("create route warning")) 482 }) 483 }) 484 }) 485 486 Describe("CreateRouteWithExistenceCheck", func() { 487 var ( 488 route Route 489 generatePort bool 490 createdRoute Route 491 createRouteWarnings Warnings 492 createRouteErr error 493 ) 494 495 BeforeEach(func() { 496 fakeCloudControllerClient.GetSpacesReturns( 497 []ccv2.Space{ 498 { 499 GUID: "some-space-guid", 500 Name: "some-space", 501 AllowSSH: true, 502 SpaceQuotaDefinitionGUID: "some-space-quota-guid", 503 }, 504 }, 505 ccv2.Warnings{"get-space-warning"}, 506 nil) 507 508 fakeCloudControllerClient.CreateRouteReturns( 509 ccv2.Route{ 510 GUID: "some-route-guid", 511 Host: "some-host", 512 Path: "some-path", 513 DomainGUID: "some-domain-guid", 514 SpaceGUID: "some-space-guid", 515 }, 516 ccv2.Warnings{"create-route-warning"}, 517 nil) 518 519 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get-routes-warning"}, nil) 520 521 route = Route{ 522 Domain: Domain{ 523 Name: "some-domain", 524 GUID: "some-domain-guid", 525 }, 526 Host: "some-host", 527 Path: "some-path", 528 } 529 generatePort = false 530 }) 531 532 JustBeforeEach(func() { 533 createdRoute, createRouteWarnings, createRouteErr = actor.CreateRouteWithExistenceCheck( 534 "some-org-guid", 535 "some-space", 536 route, 537 generatePort) 538 }) 539 540 When("route does not exist", func() { 541 BeforeEach(func() { 542 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get-routes-warning"}, nil) 543 }) 544 545 It("creates the route and returns all warnings", func() { 546 Expect(createRouteErr).ToNot(HaveOccurred()) 547 Expect(createRouteWarnings).To(ConsistOf( 548 "get-space-warning", 549 "get-routes-warning", 550 "create-route-warning", 551 )) 552 553 Expect(createdRoute).To(Equal(Route{ 554 Domain: Domain{ 555 Name: "some-domain", 556 GUID: "some-domain-guid", 557 }, 558 GUID: "some-route-guid", 559 Host: "some-host", 560 Path: "some-path", 561 SpaceGUID: "some-space-guid", 562 })) 563 564 Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(1)) 565 Expect(fakeCloudControllerClient.GetSpacesArgsForCall(0)).To(ConsistOf( 566 ccv2.Filter{ 567 Type: constant.OrganizationGUIDFilter, 568 Operator: constant.EqualOperator, 569 Values: []string{"some-org-guid"}, 570 }, 571 ccv2.Filter{ 572 Type: constant.NameFilter, 573 Operator: constant.EqualOperator, 574 Values: []string{"some-space"}, 575 })) 576 577 Expect(fakeCloudControllerClient.CreateRouteCallCount()).To(Equal(1)) 578 passedRoute, passedGeneratePort := fakeCloudControllerClient.CreateRouteArgsForCall(0) 579 Expect(passedRoute).To(Equal(ccv2.Route{ 580 DomainGUID: "some-domain-guid", 581 Host: "some-host", 582 Path: "/some-path", 583 SpaceGUID: "some-space-guid", 584 })) 585 Expect(passedGeneratePort).To(BeFalse()) 586 }) 587 588 When("creating route errors", func() { 589 var expectedErr error 590 591 BeforeEach(func() { 592 expectedErr = errors.New("map route failed") 593 fakeCloudControllerClient.CreateRouteReturns( 594 ccv2.Route{}, 595 ccv2.Warnings{"create-route-warning"}, 596 expectedErr) 597 }) 598 599 It("returns the error and warnings", func() { 600 Expect(createRouteErr).To(MatchError(expectedErr)) 601 Expect(createRouteWarnings).To(ConsistOf("get-space-warning", "get-routes-warning", "create-route-warning")) 602 }) 603 }) 604 }) 605 606 When("route already exists", func() { 607 var foundRoute ccv2.Route 608 609 BeforeEach(func() { 610 foundRoute = ccv2.Route{ 611 DomainGUID: "some-domain-guid", 612 Host: "some-host", 613 Path: "some-path", 614 Port: types.NullInt{IsSet: true, Value: 3333}, 615 SpaceGUID: "some-space-guid", 616 } 617 fakeCloudControllerClient.GetRoutesReturns( 618 []ccv2.Route{foundRoute}, 619 ccv2.Warnings{"get-routes-warning"}, 620 nil) 621 fakeCloudControllerClient.GetSharedDomainReturns( 622 ccv2.Domain{Name: "some-domain", GUID: "some-domain-guid"}, 623 ccv2.Warnings{"get-domain-warning"}, 624 nil) 625 }) 626 627 It("returns the error and warnings", func() { 628 routeString := CCToActorRoute(foundRoute, Domain{Name: "some-domain", GUID: "some-domain-guid"}).String() 629 Expect(createRouteErr).To(MatchError(actionerror.RouteAlreadyExistsError{Route: routeString})) 630 Expect(createRouteWarnings).To(ConsistOf("get-space-warning", "get-routes-warning")) 631 }) 632 }) 633 634 When("looking up the domain GUID", func() { 635 BeforeEach(func() { 636 route = Route{ 637 Domain: Domain{ 638 Name: "some-domain", 639 }, 640 } 641 }) 642 643 When("the domain exists", func() { 644 When("the domain is an HTTP domain", func() { 645 BeforeEach(func() { 646 route.Host = "some-host" 647 route.Path = "some-path" 648 649 fakeCloudControllerClient.GetSharedDomainsReturns( 650 []ccv2.Domain{}, 651 ccv2.Warnings{"get-shared-domains-warning"}, 652 nil, 653 ) 654 fakeCloudControllerClient.GetOrganizationPrivateDomainsReturns( 655 []ccv2.Domain{{Name: "some-domain", GUID: "some-requested-domain-guid"}}, 656 ccv2.Warnings{"get-private-domains-warning"}, 657 nil, 658 ) 659 }) 660 661 It("gets domain and finds route with fully instantiated domain", func() { 662 Expect(createRouteErr).ToNot(HaveOccurred()) 663 Expect(createRouteWarnings).To(ConsistOf( 664 "get-space-warning", 665 "get-shared-domains-warning", 666 "get-private-domains-warning", 667 "get-routes-warning", 668 "create-route-warning", 669 )) 670 Expect(createdRoute).To(Equal(Route{ 671 Domain: Domain{ 672 Name: "some-domain", 673 GUID: "some-requested-domain-guid", 674 }, 675 GUID: "some-route-guid", 676 Host: "some-host", 677 Path: "some-path", 678 SpaceGUID: "some-space-guid", 679 })) 680 Expect(fakeCloudControllerClient.GetSharedDomainsCallCount()).To(Equal(1)) 681 Expect(fakeCloudControllerClient.GetOrganizationPrivateDomainsCallCount()).To(Equal(1)) 682 orgGUID, queries := fakeCloudControllerClient.GetOrganizationPrivateDomainsArgsForCall(0) 683 Expect(orgGUID).To(Equal("some-org-guid")) 684 Expect(queries).To(HaveLen(1)) 685 Expect(queries[0]).To(Equal(ccv2.Filter{ 686 Type: constant.NameFilter, 687 Operator: constant.InOperator, 688 Values: []string{"some-domain"}, 689 })) 690 }) 691 }) 692 693 When("the domain is a TCP domain", func() { 694 BeforeEach(func() { 695 fakeCloudControllerClient.GetSharedDomainsReturns( 696 []ccv2.Domain{{ 697 Name: "some-tcp-domain", 698 GUID: "some-requested-domain-guid", 699 RouterGroupType: constant.TCPRouterGroup, 700 }}, 701 ccv2.Warnings{"get-shared-domains-warning"}, 702 nil, 703 ) 704 }) 705 706 When("specifying a port", func() { 707 BeforeEach(func() { 708 route.Port = types.NullInt{IsSet: true, Value: 1234} 709 fakeCloudControllerClient.CreateRouteReturns( 710 ccv2.Route{ 711 GUID: "some-route-guid", 712 DomainGUID: "some-domain-guid", 713 Port: types.NullInt{IsSet: true, Value: 1234}, 714 SpaceGUID: "some-space-guid", 715 }, 716 ccv2.Warnings{"create-route-warning"}, 717 nil) 718 }) 719 720 It("gets domain and finds route with fully instantiated domain", func() { 721 Expect(createRouteErr).ToNot(HaveOccurred()) 722 Expect(createRouteWarnings).To(ConsistOf( 723 "get-space-warning", 724 "get-shared-domains-warning", 725 "get-routes-warning", 726 "create-route-warning", 727 )) 728 Expect(createdRoute).To(Equal(Route{ 729 Domain: Domain{ 730 Name: "some-domain", 731 GUID: "some-requested-domain-guid", 732 RouterGroupType: constant.TCPRouterGroup, 733 }, 734 GUID: "some-route-guid", 735 Port: types.NullInt{IsSet: true, Value: 1234}, 736 SpaceGUID: "some-space-guid", 737 })) 738 Expect(fakeCloudControllerClient.GetSharedDomainsCallCount()).To(Equal(1)) 739 Expect(fakeCloudControllerClient.GetOrganizationPrivateDomainsCallCount()).To(Equal(1)) 740 orgGUID, queries := fakeCloudControllerClient.GetOrganizationPrivateDomainsArgsForCall(0) 741 Expect(orgGUID).To(Equal("some-org-guid")) 742 Expect(queries).To(HaveLen(1)) 743 Expect(queries[0]).To(Equal(ccv2.Filter{ 744 Type: constant.NameFilter, 745 Operator: constant.InOperator, 746 Values: []string{"some-domain"}, 747 })) 748 749 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 750 }) 751 }) 752 753 When("generating a random port", func() { 754 BeforeEach(func() { 755 generatePort = true 756 fakeCloudControllerClient.CreateRouteReturns( 757 ccv2.Route{ 758 GUID: "some-route-guid", 759 DomainGUID: "some-domain-guid", 760 Port: types.NullInt{IsSet: true, Value: 1234}, 761 SpaceGUID: "some-space-guid", 762 }, 763 ccv2.Warnings{"create-route-warning"}, 764 nil) 765 }) 766 767 It("creates a route with a generated port, and doesn't check for existence", func() { 768 Expect(createRouteErr).ToNot(HaveOccurred()) 769 Expect(createRouteWarnings).To(ConsistOf( 770 "get-space-warning", 771 "get-shared-domains-warning", 772 "create-route-warning", 773 )) 774 Expect(createdRoute).To(Equal(Route{ 775 Domain: Domain{ 776 Name: "some-domain", 777 GUID: "some-requested-domain-guid", 778 RouterGroupType: constant.TCPRouterGroup, 779 }, 780 GUID: "some-route-guid", 781 Port: types.NullInt{IsSet: true, Value: 1234}, 782 SpaceGUID: "some-space-guid", 783 })) 784 Expect(fakeCloudControllerClient.GetSharedDomainsCallCount()).To(Equal(1)) 785 Expect(fakeCloudControllerClient.GetOrganizationPrivateDomainsCallCount()).To(Equal(1)) 786 orgGUID, queries := fakeCloudControllerClient.GetOrganizationPrivateDomainsArgsForCall(0) 787 Expect(orgGUID).To(Equal("some-org-guid")) 788 Expect(queries).To(HaveLen(1)) 789 Expect(queries[0]).To(Equal(ccv2.Filter{ 790 Type: constant.NameFilter, 791 Operator: constant.InOperator, 792 Values: []string{"some-domain"}, 793 })) 794 795 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(0)) 796 }) 797 }) 798 799 When("no port options are provided", func() { 800 BeforeEach(func() { 801 generatePort = false 802 route.Port.IsSet = false 803 }) 804 805 It("returns a TCPRouteOptionsNotProvidedError", func() { 806 Expect(createRouteErr).To(MatchError(actionerror.TCPRouteOptionsNotProvidedError{})) 807 }) 808 }) 809 }) 810 }) 811 812 When("the domain doesn't exist", func() { 813 BeforeEach(func() { 814 fakeCloudControllerClient.GetSharedDomainsReturns( 815 []ccv2.Domain{}, 816 ccv2.Warnings{"get-shared-domains-warning"}, 817 nil, 818 ) 819 fakeCloudControllerClient.GetOrganizationPrivateDomainsReturns( 820 []ccv2.Domain{}, 821 ccv2.Warnings{"get-private-domains-warning"}, 822 nil, 823 ) 824 }) 825 826 It("returns all warnings and domain not found err", func() { 827 Expect(createRouteErr).To(Equal(actionerror.DomainNotFoundError{Name: "some-domain"})) 828 Expect(createRouteWarnings).To(ConsistOf( 829 "get-space-warning", 830 "get-shared-domains-warning", 831 "get-private-domains-warning", 832 )) 833 }) 834 }) 835 }) 836 837 When("the requested route is invalid", func() { 838 BeforeEach(func() { 839 generatePort = true 840 }) 841 842 It("returns a validation error", func() { 843 Expect(createRouteErr).To(MatchError(actionerror.InvalidHTTPRouteSettings{Domain: route.Domain.Name})) 844 Expect(createRouteWarnings).To(ConsistOf("get-space-warning")) 845 }) 846 }) 847 848 When("getting space errors", func() { 849 var expectedErr error 850 851 BeforeEach(func() { 852 expectedErr = errors.New("map route failed") 853 fakeCloudControllerClient.GetSpacesReturns( 854 []ccv2.Space{}, 855 ccv2.Warnings{"get-space-warning"}, 856 expectedErr) 857 }) 858 859 It("returns the error and warnings", func() { 860 Expect(createRouteErr).To(MatchError(expectedErr)) 861 Expect(createRouteWarnings).To(ConsistOf("get-space-warning")) 862 }) 863 }) 864 865 When("getting routes errors", func() { 866 var expectedErr error 867 868 BeforeEach(func() { 869 expectedErr = errors.New("map route failed") 870 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get-routes-warning"}, expectedErr) 871 }) 872 873 It("returns the error and warnings", func() { 874 Expect(createRouteErr).To(MatchError(expectedErr)) 875 Expect(createRouteWarnings).To(ConsistOf("get-space-warning", "get-routes-warning")) 876 }) 877 }) 878 }) 879 880 Describe("GetOrphanedRoutesBySpace", func() { 881 BeforeEach(func() { 882 fakeCloudControllerClient.GetRouteApplicationsStub = func(routeGUID string, queries ...ccv2.Filter) ([]ccv2.Application, ccv2.Warnings, error) { 883 switch routeGUID { 884 case "orphaned-route-guid-1": 885 return []ccv2.Application{}, nil, nil 886 case "orphaned-route-guid-2": 887 return []ccv2.Application{}, nil, nil 888 case "not-orphaned-route-guid-3": 889 return []ccv2.Application{ 890 {GUID: "app-guid"}, 891 }, nil, nil 892 } 893 Fail("Unexpected route-guid") 894 return []ccv2.Application{}, nil, nil 895 } 896 }) 897 898 When("there are orphaned routes", func() { 899 BeforeEach(func() { 900 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 901 { 902 GUID: "orphaned-route-guid-1", 903 DomainGUID: "some-domain-guid", 904 }, 905 { 906 GUID: "orphaned-route-guid-2", 907 DomainGUID: "some-other-domain-guid", 908 }, 909 { 910 GUID: "not-orphaned-route-guid-3", 911 DomainGUID: "not-orphaned-route-domain-guid", 912 }, 913 }, nil, nil) 914 fakeCloudControllerClient.GetSharedDomainStub = func(domainGUID string) (ccv2.Domain, ccv2.Warnings, error) { 915 switch domainGUID { 916 case "some-domain-guid": 917 return ccv2.Domain{ 918 GUID: "some-domain-guid", 919 Name: "some-domain.com", 920 }, nil, nil 921 case "some-other-domain-guid": 922 return ccv2.Domain{ 923 GUID: "some-other-domain-guid", 924 Name: "some-other-domain.com", 925 }, nil, nil 926 case "not-orphaned-route-domain-guid": 927 return ccv2.Domain{ 928 GUID: "not-orphaned-route-domain-guid", 929 Name: "not-orphaned-route-domain.com", 930 }, nil, nil 931 } 932 return ccv2.Domain{}, nil, errors.New("Unexpected domain GUID") 933 } 934 }) 935 936 It("returns the orphaned routes with the domain names", func() { 937 orphanedRoutes, _, err := actor.GetOrphanedRoutesBySpace("space-guid") 938 Expect(err).NotTo(HaveOccurred()) 939 Expect(orphanedRoutes).To(ConsistOf([]Route{ 940 { 941 GUID: "orphaned-route-guid-1", 942 Domain: Domain{ 943 Name: "some-domain.com", 944 GUID: "some-domain-guid", 945 }, 946 }, 947 { 948 GUID: "orphaned-route-guid-2", 949 Domain: Domain{ 950 Name: "some-other-domain.com", 951 GUID: "some-other-domain-guid", 952 }, 953 }, 954 })) 955 956 Expect(fakeCloudControllerClient.GetSpaceRoutesCallCount()).To(Equal(1)) 957 958 spaceGUID, queries := fakeCloudControllerClient.GetSpaceRoutesArgsForCall(0) 959 Expect(spaceGUID).To(Equal("space-guid")) 960 Expect(queries).To(BeNil()) 961 962 Expect(fakeCloudControllerClient.GetRouteApplicationsCallCount()).To(Equal(3)) 963 964 routeGUID, queries := fakeCloudControllerClient.GetRouteApplicationsArgsForCall(0) 965 Expect(routeGUID).To(Equal("orphaned-route-guid-1")) 966 Expect(queries).To(BeNil()) 967 968 routeGUID, queries = fakeCloudControllerClient.GetRouteApplicationsArgsForCall(1) 969 Expect(routeGUID).To(Equal("orphaned-route-guid-2")) 970 Expect(queries).To(BeNil()) 971 972 routeGUID, queries = fakeCloudControllerClient.GetRouteApplicationsArgsForCall(2) 973 Expect(routeGUID).To(Equal("not-orphaned-route-guid-3")) 974 Expect(queries).To(BeNil()) 975 }) 976 }) 977 978 When("there are no orphaned routes", func() { 979 var expectedErr actionerror.OrphanedRoutesNotFoundError 980 981 BeforeEach(func() { 982 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 983 ccv2.Route{GUID: "not-orphaned-route-guid-3"}, 984 }, nil, nil) 985 }) 986 987 It("returns an OrphanedRoutesNotFoundError", func() { 988 orphanedRoutes, _, err := actor.GetOrphanedRoutesBySpace("space-guid") 989 Expect(err).To(MatchError(expectedErr)) 990 Expect(orphanedRoutes).To(BeNil()) 991 992 Expect(fakeCloudControllerClient.GetSpaceRoutesCallCount()).To(Equal(1)) 993 994 spaceGUID, queries := fakeCloudControllerClient.GetSpaceRoutesArgsForCall(0) 995 Expect(spaceGUID).To(Equal("space-guid")) 996 Expect(queries).To(BeNil()) 997 998 Expect(fakeCloudControllerClient.GetRouteApplicationsCallCount()).To(Equal(1)) 999 1000 routeGUID, queries := fakeCloudControllerClient.GetRouteApplicationsArgsForCall(0) 1001 Expect(routeGUID).To(Equal("not-orphaned-route-guid-3")) 1002 Expect(queries).To(BeNil()) 1003 }) 1004 }) 1005 1006 When("there are warnings", func() { 1007 BeforeEach(func() { 1008 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 1009 ccv2.Route{GUID: "route-guid-1"}, 1010 ccv2.Route{GUID: "route-guid-2"}, 1011 }, ccv2.Warnings{"get-routes-warning"}, nil) 1012 fakeCloudControllerClient.GetRouteApplicationsReturns(nil, ccv2.Warnings{"get-applications-warning"}, nil) 1013 fakeCloudControllerClient.GetSharedDomainReturns(ccv2.Domain{GUID: "some-guid"}, ccv2.Warnings{"get-shared-domain-warning"}, nil) 1014 }) 1015 1016 It("returns all the warnings", func() { 1017 _, warnings, err := actor.GetOrphanedRoutesBySpace("space-guid") 1018 Expect(err).NotTo(HaveOccurred()) 1019 Expect(warnings).To(ConsistOf("get-routes-warning", "get-applications-warning", "get-shared-domain-warning", "get-applications-warning", "get-shared-domain-warning")) 1020 }) 1021 }) 1022 1023 When("the spaces routes API request returns an error", func() { 1024 var expectedErr error 1025 1026 BeforeEach(func() { 1027 expectedErr = errors.New("spaces routes error") 1028 fakeCloudControllerClient.GetSpaceRoutesReturns(nil, nil, expectedErr) 1029 }) 1030 1031 It("returns the error", func() { 1032 routes, _, err := actor.GetOrphanedRoutesBySpace("space-guid") 1033 Expect(err).To(Equal(expectedErr)) 1034 Expect(routes).To(BeNil()) 1035 }) 1036 }) 1037 1038 When("a route's applications API request returns an error", func() { 1039 var expectedErr error 1040 1041 BeforeEach(func() { 1042 expectedErr = errors.New("application error") 1043 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 1044 ccv2.Route{GUID: "route-guid"}, 1045 }, nil, nil) 1046 fakeCloudControllerClient.GetRouteApplicationsReturns(nil, nil, expectedErr) 1047 }) 1048 1049 It("returns the error", func() { 1050 routes, _, err := actor.GetOrphanedRoutesBySpace("space-guid") 1051 Expect(err).To(Equal(expectedErr)) 1052 Expect(routes).To(BeNil()) 1053 }) 1054 }) 1055 }) 1056 1057 Describe("DeleteRoute", func() { 1058 When("the route exists", func() { 1059 BeforeEach(func() { 1060 fakeCloudControllerClient.DeleteRouteReturns(nil, nil) 1061 }) 1062 1063 It("deletes the route", func() { 1064 _, err := actor.DeleteRoute("some-route-guid") 1065 Expect(err).NotTo(HaveOccurred()) 1066 1067 Expect(fakeCloudControllerClient.DeleteRouteCallCount()).To(Equal(1)) 1068 Expect(fakeCloudControllerClient.DeleteRouteArgsForCall(0)).To(Equal("some-route-guid")) 1069 }) 1070 }) 1071 1072 When("the API returns both warnings and an error", func() { 1073 var expectedErr error 1074 1075 BeforeEach(func() { 1076 expectedErr = errors.New("bananahammock") 1077 fakeCloudControllerClient.DeleteRouteReturns(ccv2.Warnings{"foo", "bar"}, expectedErr) 1078 }) 1079 1080 It("returns both the warnings and the error", func() { 1081 warnings, err := actor.DeleteRoute("some-route-guid") 1082 Expect(err).To(MatchError(expectedErr)) 1083 Expect(warnings).To(ConsistOf("foo", "bar")) 1084 }) 1085 }) 1086 }) 1087 1088 Describe("GetApplicationRoutes", func() { 1089 When("the CC API client does not return any errors", func() { 1090 BeforeEach(func() { 1091 fakeCloudControllerClient.GetApplicationRoutesReturns([]ccv2.Route{ 1092 ccv2.Route{ 1093 GUID: "route-guid-1", 1094 SpaceGUID: "some-space-guid", 1095 Host: "host", 1096 Path: "/path", 1097 Port: types.NullInt{IsSet: true, Value: 1234}, 1098 DomainGUID: "domain-1-guid", 1099 }, 1100 ccv2.Route{ 1101 GUID: "route-guid-2", 1102 SpaceGUID: "some-space-guid", 1103 Host: "host", 1104 Path: "/path", 1105 Port: types.NullInt{IsSet: true, Value: 1234}, 1106 DomainGUID: "domain-2-guid", 1107 }, 1108 }, ccv2.Warnings{"get-application-routes-warning"}, nil) 1109 1110 fakeCloudControllerClient.GetSharedDomainReturnsOnCall(0, ccv2.Domain{Name: "domain.com"}, nil, nil) 1111 fakeCloudControllerClient.GetSharedDomainReturnsOnCall(1, ccv2.Domain{Name: "other-domain.com"}, nil, nil) 1112 }) 1113 1114 It("returns the application routes and any warnings", func() { 1115 routes, warnings, err := actor.GetApplicationRoutes("application-guid") 1116 Expect(fakeCloudControllerClient.GetApplicationRoutesCallCount()).To(Equal(1)) 1117 Expect(fakeCloudControllerClient.GetApplicationRoutesArgsForCall(0)).To(Equal("application-guid")) 1118 Expect(fakeCloudControllerClient.GetSharedDomainCallCount()).To(Equal(2)) 1119 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(0)).To(Equal("domain-1-guid")) 1120 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(1)).To(Equal("domain-2-guid")) 1121 1122 Expect(warnings).To(ConsistOf("get-application-routes-warning")) 1123 Expect(err).NotTo(HaveOccurred()) 1124 Expect(routes).To(ConsistOf([]Route{ 1125 { 1126 Domain: Domain{ 1127 Name: "domain.com", 1128 }, 1129 GUID: "route-guid-1", 1130 Host: "host", 1131 Path: "/path", 1132 Port: types.NullInt{IsSet: true, Value: 1234}, 1133 SpaceGUID: "some-space-guid", 1134 }, 1135 { 1136 Domain: Domain{ 1137 Name: "other-domain.com", 1138 }, 1139 GUID: "route-guid-2", 1140 Host: "host", 1141 Path: "/path", 1142 Port: types.NullInt{IsSet: true, Value: 1234}, 1143 SpaceGUID: "some-space-guid", 1144 }, 1145 })) 1146 }) 1147 }) 1148 1149 When("the CC API client returns an error", func() { 1150 When("getting application routes returns an error and warnings", func() { 1151 BeforeEach(func() { 1152 fakeCloudControllerClient.GetApplicationRoutesReturns( 1153 []ccv2.Route{}, ccv2.Warnings{"application-routes-warning"}, errors.New("get-application-routes-error")) 1154 }) 1155 1156 It("returns the error and warnings", func() { 1157 routes, warnings, err := actor.GetApplicationRoutes("application-guid") 1158 Expect(warnings).To(ConsistOf("application-routes-warning")) 1159 Expect(err).To(MatchError("get-application-routes-error")) 1160 Expect(routes).To(BeNil()) 1161 }) 1162 }) 1163 1164 When("getting the domain returns an error and warnings", func() { 1165 BeforeEach(func() { 1166 fakeCloudControllerClient.GetApplicationRoutesReturns([]ccv2.Route{ 1167 ccv2.Route{ 1168 GUID: "route-guid-1", 1169 SpaceGUID: "some-space-guid", 1170 Host: "host", 1171 Path: "/path", 1172 Port: types.NullInt{IsSet: true, Value: 1234}, 1173 DomainGUID: "domain-1-guid", 1174 }, 1175 }, nil, nil) 1176 fakeCloudControllerClient.GetSharedDomainReturns(ccv2.Domain{}, ccv2.Warnings{"domain-warning"}, errors.New("get-domain-error")) 1177 }) 1178 1179 It("returns the error and warnings", func() { 1180 routes, warnings, err := actor.GetApplicationRoutes("application-guid") 1181 Expect(warnings).To(ConsistOf("domain-warning")) 1182 Expect(err).To(MatchError("get-domain-error")) 1183 Expect(routes).To(BeNil()) 1184 1185 Expect(fakeCloudControllerClient.GetSharedDomainCallCount()).To(Equal(1)) 1186 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(0)).To(Equal("domain-1-guid")) 1187 }) 1188 }) 1189 }) 1190 1191 When("the CC API client returns warnings and no errors", func() { 1192 BeforeEach(func() { 1193 fakeCloudControllerClient.GetApplicationRoutesReturns([]ccv2.Route{ 1194 ccv2.Route{ 1195 GUID: "route-guid-1", 1196 SpaceGUID: "some-space-guid", 1197 Host: "host", 1198 Path: "/path", 1199 Port: types.NullInt{IsSet: true, Value: 1234}, 1200 DomainGUID: "domain-1-guid", 1201 }, 1202 }, ccv2.Warnings{"application-routes-warning"}, nil) 1203 fakeCloudControllerClient.GetSharedDomainReturns(ccv2.Domain{}, ccv2.Warnings{"domain-warning"}, nil) 1204 }) 1205 1206 It("returns the warnings", func() { 1207 _, warnings, _ := actor.GetApplicationRoutes("application-guid") 1208 Expect(warnings).To(ConsistOf("application-routes-warning", "domain-warning")) 1209 }) 1210 }) 1211 }) 1212 1213 Describe("GetSpaceRoutes", func() { 1214 When("the CC API client does not return any errors", func() { 1215 BeforeEach(func() { 1216 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 1217 ccv2.Route{ 1218 GUID: "route-guid-1", 1219 SpaceGUID: "some-space-guid", 1220 Host: "host", 1221 Path: "/path", 1222 Port: types.NullInt{IsSet: true, Value: 1234}, 1223 DomainGUID: "domain-1-guid", 1224 }, 1225 ccv2.Route{ 1226 GUID: "route-guid-2", 1227 SpaceGUID: "some-space-guid", 1228 Host: "host", 1229 Path: "/path", 1230 Port: types.NullInt{IsSet: true, Value: 1234}, 1231 DomainGUID: "domain-2-guid", 1232 }, 1233 }, ccv2.Warnings{"get-space-routes-warning"}, nil) 1234 fakeCloudControllerClient.GetSharedDomainReturnsOnCall(0, ccv2.Domain{Name: "domain.com"}, nil, nil) 1235 fakeCloudControllerClient.GetSharedDomainReturnsOnCall(1, ccv2.Domain{Name: "other-domain.com"}, nil, nil) 1236 }) 1237 1238 It("returns the space routes and any warnings", func() { 1239 routes, warnings, err := actor.GetSpaceRoutes("space-guid") 1240 Expect(fakeCloudControllerClient.GetSpaceRoutesCallCount()).To(Equal(1)) 1241 Expect(fakeCloudControllerClient.GetSpaceRoutesArgsForCall(0)).To(Equal("space-guid")) 1242 Expect(fakeCloudControllerClient.GetSharedDomainCallCount()).To(Equal(2)) 1243 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(0)).To(Equal("domain-1-guid")) 1244 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(1)).To(Equal("domain-2-guid")) 1245 1246 Expect(warnings).To(ConsistOf("get-space-routes-warning")) 1247 Expect(err).NotTo(HaveOccurred()) 1248 Expect(routes).To(ConsistOf([]Route{ 1249 { 1250 Domain: Domain{ 1251 Name: "domain.com", 1252 }, 1253 GUID: "route-guid-1", 1254 Host: "host", 1255 Path: "/path", 1256 Port: types.NullInt{IsSet: true, Value: 1234}, 1257 SpaceGUID: "some-space-guid", 1258 }, 1259 { 1260 Domain: Domain{ 1261 Name: "other-domain.com", 1262 }, 1263 GUID: "route-guid-2", 1264 Host: "host", 1265 Path: "/path", 1266 Port: types.NullInt{IsSet: true, Value: 1234}, 1267 SpaceGUID: "some-space-guid", 1268 }, 1269 })) 1270 }) 1271 }) 1272 1273 When("the CC API client returns an error", func() { 1274 When("getting space routes returns an error and warnings", func() { 1275 BeforeEach(func() { 1276 fakeCloudControllerClient.GetSpaceRoutesReturns( 1277 []ccv2.Route{}, ccv2.Warnings{"space-routes-warning"}, errors.New("get-space-routes-error")) 1278 }) 1279 1280 It("returns the error and warnings", func() { 1281 routes, warnings, err := actor.GetSpaceRoutes("space-guid") 1282 Expect(warnings).To(ConsistOf("space-routes-warning")) 1283 Expect(err).To(MatchError("get-space-routes-error")) 1284 Expect(routes).To(BeNil()) 1285 }) 1286 }) 1287 1288 When("getting the domain returns an error and warnings", func() { 1289 BeforeEach(func() { 1290 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 1291 ccv2.Route{ 1292 GUID: "route-guid-1", 1293 SpaceGUID: "some-space-guid", 1294 Host: "host", 1295 Path: "/path", 1296 Port: types.NullInt{IsSet: true, Value: 1234}, 1297 DomainGUID: "domain-1-guid", 1298 }, 1299 }, nil, nil) 1300 fakeCloudControllerClient.GetSharedDomainReturns(ccv2.Domain{}, ccv2.Warnings{"domain-warning"}, errors.New("get-domain-error")) 1301 }) 1302 1303 It("returns the error and warnings", func() { 1304 routes, warnings, err := actor.GetSpaceRoutes("space-guid") 1305 Expect(fakeCloudControllerClient.GetSharedDomainCallCount()).To(Equal(1)) 1306 Expect(fakeCloudControllerClient.GetSharedDomainArgsForCall(0)).To(Equal("domain-1-guid")) 1307 1308 Expect(warnings).To(ConsistOf("domain-warning")) 1309 Expect(err).To(MatchError("get-domain-error")) 1310 Expect(routes).To(BeNil()) 1311 }) 1312 }) 1313 }) 1314 1315 When("the CC API client returns warnings and no errors", func() { 1316 BeforeEach(func() { 1317 fakeCloudControllerClient.GetSpaceRoutesReturns([]ccv2.Route{ 1318 ccv2.Route{ 1319 GUID: "route-guid-1", 1320 SpaceGUID: "some-space-guid", 1321 Host: "host", 1322 Path: "/path", 1323 Port: types.NullInt{IsSet: true, Value: 1234}, 1324 DomainGUID: "domain-1-guid", 1325 }, 1326 }, ccv2.Warnings{"space-routes-warning"}, nil) 1327 fakeCloudControllerClient.GetSharedDomainReturns(ccv2.Domain{}, ccv2.Warnings{"domain-warning"}, nil) 1328 }) 1329 1330 It("returns the warnings", func() { 1331 _, warnings, _ := actor.GetSpaceRoutes("space-guid") 1332 Expect(warnings).To(ConsistOf("space-routes-warning", "domain-warning")) 1333 }) 1334 }) 1335 }) 1336 1337 Describe("GetRouteByComponents", func() { 1338 var ( 1339 domain Domain 1340 inputRoute Route 1341 1342 route Route 1343 warnings Warnings 1344 executeErr error 1345 ) 1346 1347 BeforeEach(func() { 1348 domain = Domain{ 1349 GUID: "some-domain-guid", 1350 Name: "domain.com", 1351 } 1352 1353 inputRoute = Route{ 1354 Domain: domain, 1355 } 1356 }) 1357 1358 JustBeforeEach(func() { 1359 route, warnings, executeErr = actor.GetRouteByComponents(inputRoute) 1360 }) 1361 1362 Context("validation", func() { 1363 When("the route's domain is a TCP domain", func() { 1364 BeforeEach(func() { 1365 inputRoute.Domain.RouterGroupType = constant.TCPRouterGroup 1366 }) 1367 1368 When("a port isn't provided for the query", func() { 1369 BeforeEach(func() { 1370 inputRoute.Port.IsSet = false 1371 }) 1372 1373 It("returns a PortNotProvidedForQueryError", func() { 1374 Expect(executeErr).To(MatchError(actionerror.PortNotProvidedForQueryError{})) 1375 }) 1376 }) 1377 }) 1378 1379 When("the route's domain is an HTTP shared domain", func() { 1380 BeforeEach(func() { 1381 inputRoute.Domain.RouterGroupType = constant.HTTPRouterGroup 1382 inputRoute.Domain.Type = constant.SharedDomain 1383 }) 1384 1385 When("a host is not provided", func() { 1386 BeforeEach(func() { 1387 inputRoute.Host = "" 1388 }) 1389 1390 It("returns a NoHostnameAndSharedDomainError", func() { 1391 Expect(executeErr).To(MatchError(actionerror.NoHostnameAndSharedDomainError{})) 1392 }) 1393 }) 1394 }) 1395 }) 1396 1397 When("finding the route is successful and returns one route", func() { 1398 When("hostname and path aren't provided", func() { 1399 BeforeEach(func() { 1400 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ 1401 { 1402 GUID: "route-guid-1", 1403 SpaceGUID: "some-space-guid", 1404 DomainGUID: domain.GUID, 1405 }, 1406 }, ccv2.Warnings{"get-routes-warning"}, nil) 1407 }) 1408 1409 It("explicitly queries for empty hostname and path", func() { 1410 Expect(warnings).To(ConsistOf("get-routes-warning")) 1411 Expect(executeErr).NotTo(HaveOccurred()) 1412 Expect(route).To(Equal(Route{ 1413 Domain: domain, 1414 GUID: "route-guid-1", 1415 Host: inputRoute.Host, 1416 SpaceGUID: "some-space-guid", 1417 })) 1418 1419 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 1420 Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(Equal([]ccv2.Filter{ 1421 { 1422 Type: constant.DomainGUIDFilter, 1423 Operator: constant.EqualOperator, 1424 Values: []string{domain.GUID}, 1425 }, 1426 { 1427 Type: constant.HostFilter, 1428 Operator: constant.EqualOperator, 1429 Values: []string{""}, 1430 }, 1431 { 1432 Type: constant.PathFilter, 1433 Operator: constant.EqualOperator, 1434 Values: []string{""}, 1435 }, 1436 })) 1437 }) 1438 }) 1439 1440 When("the hostname is provided", func() { 1441 BeforeEach(func() { 1442 inputRoute.Host = "some-host" 1443 1444 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ 1445 { 1446 GUID: "route-guid-1", 1447 SpaceGUID: "some-space-guid", 1448 Host: inputRoute.Host, 1449 DomainGUID: domain.GUID, 1450 }, 1451 }, ccv2.Warnings{"get-routes-warning"}, nil) 1452 }) 1453 1454 It("returns the route and any warnings", func() { 1455 Expect(warnings).To(ConsistOf("get-routes-warning")) 1456 Expect(executeErr).NotTo(HaveOccurred()) 1457 Expect(route).To(Equal(Route{ 1458 Domain: domain, 1459 GUID: "route-guid-1", 1460 Host: inputRoute.Host, 1461 SpaceGUID: "some-space-guid", 1462 })) 1463 1464 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 1465 Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(Equal([]ccv2.Filter{ 1466 { 1467 Type: constant.DomainGUIDFilter, 1468 Operator: constant.EqualOperator, 1469 Values: []string{domain.GUID}, 1470 }, 1471 { 1472 Type: constant.HostFilter, 1473 Operator: constant.EqualOperator, 1474 Values: []string{inputRoute.Host}, 1475 }, 1476 { 1477 Type: constant.PathFilter, 1478 Operator: constant.EqualOperator, 1479 Values: []string{""}, 1480 }, 1481 })) 1482 }) 1483 }) 1484 1485 When("the path is provided", func() { 1486 BeforeEach(func() { 1487 inputRoute.Path = "/some-path" 1488 1489 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ 1490 { 1491 GUID: "route-guid-1", 1492 SpaceGUID: "some-space-guid", 1493 Path: inputRoute.Path, 1494 DomainGUID: domain.GUID, 1495 }, 1496 }, ccv2.Warnings{"get-routes-warning"}, nil) 1497 }) 1498 1499 It("returns the routes and any warnings", func() { 1500 Expect(warnings).To(ConsistOf("get-routes-warning")) 1501 Expect(executeErr).NotTo(HaveOccurred()) 1502 Expect(route).To(Equal(Route{ 1503 Domain: domain, 1504 GUID: "route-guid-1", 1505 Path: inputRoute.Path, 1506 SpaceGUID: "some-space-guid", 1507 })) 1508 1509 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 1510 Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(Equal([]ccv2.Filter{ 1511 { 1512 Type: constant.DomainGUIDFilter, 1513 Operator: constant.EqualOperator, 1514 Values: []string{domain.GUID}, 1515 }, 1516 { 1517 Type: constant.HostFilter, 1518 Operator: constant.EqualOperator, 1519 Values: []string{inputRoute.Host}, 1520 }, 1521 { 1522 Type: constant.PathFilter, 1523 Operator: constant.EqualOperator, 1524 Values: []string{inputRoute.Path}, 1525 }, 1526 })) 1527 }) 1528 }) 1529 1530 When("the port is provided", func() { 1531 BeforeEach(func() { 1532 inputRoute.Port = types.NullInt{Value: 1234, IsSet: true} 1533 1534 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ 1535 { 1536 GUID: "route-guid-1", 1537 SpaceGUID: "some-space-guid", 1538 Port: inputRoute.Port, 1539 DomainGUID: domain.GUID, 1540 }, 1541 }, ccv2.Warnings{"get-routes-warning"}, nil) 1542 }) 1543 1544 It("returns the routes and any warnings", func() { 1545 Expect(warnings).To(ConsistOf("get-routes-warning")) 1546 Expect(executeErr).NotTo(HaveOccurred()) 1547 Expect(route).To(Equal(Route{ 1548 Domain: domain, 1549 GUID: "route-guid-1", 1550 Port: inputRoute.Port, 1551 SpaceGUID: "some-space-guid", 1552 })) 1553 1554 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 1555 Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(Equal([]ccv2.Filter{ 1556 { 1557 Type: constant.DomainGUIDFilter, 1558 Operator: constant.EqualOperator, 1559 Values: []string{domain.GUID}, 1560 }, 1561 { 1562 Type: constant.HostFilter, 1563 Operator: constant.EqualOperator, 1564 Values: []string{inputRoute.Host}, 1565 }, 1566 { 1567 Type: constant.PathFilter, 1568 Operator: constant.EqualOperator, 1569 Values: []string{inputRoute.Path}, 1570 }, 1571 { 1572 Type: constant.PortFilter, 1573 Operator: constant.EqualOperator, 1574 Values: []string{fmt.Sprint(inputRoute.Port.Value)}, 1575 }, 1576 })) 1577 }) 1578 }) 1579 1580 When("all parts of the route are provided", func() { 1581 BeforeEach(func() { 1582 inputRoute.Host = "some-host" 1583 inputRoute.Path = "/some-path" 1584 inputRoute.Port = types.NullInt{Value: 1234, IsSet: true} 1585 1586 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{{ 1587 DomainGUID: domain.GUID, 1588 GUID: "route-guid-1", 1589 Host: inputRoute.Host, 1590 Path: inputRoute.Path, 1591 Port: inputRoute.Port, 1592 SpaceGUID: "some-space-guid", 1593 }}, ccv2.Warnings{"get-routes-warning"}, nil) 1594 }) 1595 1596 It("returns the routes and any warnings", func() { 1597 Expect(warnings).To(ConsistOf("get-routes-warning")) 1598 Expect(executeErr).NotTo(HaveOccurred()) 1599 Expect(route).To(Equal(Route{ 1600 Domain: domain, 1601 GUID: "route-guid-1", 1602 Host: inputRoute.Host, 1603 Path: inputRoute.Path, 1604 Port: inputRoute.Port, 1605 SpaceGUID: "some-space-guid", 1606 })) 1607 1608 Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1)) 1609 Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(Equal([]ccv2.Filter{ 1610 { 1611 Type: constant.DomainGUIDFilter, 1612 Operator: constant.EqualOperator, 1613 Values: []string{domain.GUID}, 1614 }, 1615 { 1616 Type: constant.HostFilter, 1617 Operator: constant.EqualOperator, 1618 Values: []string{inputRoute.Host}, 1619 }, 1620 { 1621 Type: constant.PathFilter, 1622 Operator: constant.EqualOperator, 1623 Values: []string{inputRoute.Path}, 1624 }, 1625 { 1626 Type: constant.PortFilter, 1627 Operator: constant.EqualOperator, 1628 Values: []string{fmt.Sprint(inputRoute.Port.Value)}, 1629 }, 1630 })) 1631 }) 1632 }) 1633 }) 1634 1635 When("finding the route is successful and returns no routes", func() { 1636 BeforeEach(func() { 1637 inputRoute.Host = "some-host" 1638 inputRoute.Path = "/some-path" 1639 inputRoute.Port = types.NullInt{Value: 1234, IsSet: true} 1640 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get-routes-warning"}, nil) 1641 }) 1642 1643 It("returns a RouteNotFoundError and warnings", func() { 1644 Expect(executeErr).To(MatchError(actionerror.RouteNotFoundError{ 1645 Host: inputRoute.Host, 1646 Path: inputRoute.Path, 1647 Port: inputRoute.Port.Value, 1648 DomainGUID: domain.GUID, 1649 })) 1650 Expect(warnings).To(ConsistOf("get-routes-warning")) 1651 }) 1652 }) 1653 1654 When("finding the route returns an error", func() { 1655 var expectedErr error 1656 1657 BeforeEach(func() { 1658 expectedErr = errors.New("get-routes-err") 1659 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get-routes-warning"}, expectedErr) 1660 }) 1661 1662 It("returns the error and warnings", func() { 1663 Expect(executeErr).To(MatchError(expectedErr)) 1664 Expect(warnings).To(ConsistOf("get-routes-warning")) 1665 }) 1666 }) 1667 }) 1668 1669 Describe("CheckRoute", func() { 1670 When("the API calls succeed", func() { 1671 BeforeEach(func() { 1672 fakeCloudControllerClient.CheckRouteReturns(true, ccv2.Warnings{"some-check-route-warnings"}, nil) 1673 }) 1674 1675 It("returns the bool and warnings", func() { 1676 exists, warnings, err := actor.CheckRoute(Route{ 1677 Host: "some-host", 1678 Domain: Domain{ 1679 GUID: "some-domain-guid", 1680 }, 1681 Path: "some-path", 1682 Port: types.NullInt{IsSet: true, Value: 42}, 1683 }) 1684 1685 Expect(err).ToNot(HaveOccurred()) 1686 Expect(warnings).To(ConsistOf("some-check-route-warnings")) 1687 Expect(exists).To(BeTrue()) 1688 1689 Expect(fakeCloudControllerClient.CheckRouteCallCount()).To(Equal(1)) 1690 Expect(fakeCloudControllerClient.CheckRouteArgsForCall(0)).To(Equal(ccv2.Route{ 1691 Host: "some-host", 1692 DomainGUID: "some-domain-guid", 1693 Path: "some-path", 1694 Port: types.NullInt{IsSet: true, Value: 42}, 1695 })) 1696 }) 1697 }) 1698 1699 When("the cc returns an error", func() { 1700 var expectedErr error 1701 1702 BeforeEach(func() { 1703 expectedErr = errors.New("booo") 1704 fakeCloudControllerClient.CheckRouteReturns(false, ccv2.Warnings{"some-check-route-warnings"}, expectedErr) 1705 }) 1706 1707 It("returns the bool and warnings", func() { 1708 exists, warnings, err := actor.CheckRoute(Route{ 1709 Host: "some-host", 1710 Domain: Domain{ 1711 GUID: "some-domain-guid", 1712 }, 1713 }) 1714 1715 Expect(err).To(MatchError(expectedErr)) 1716 Expect(warnings).To(ConsistOf("some-check-route-warnings")) 1717 Expect(exists).To(BeFalse()) 1718 }) 1719 }) 1720 }) 1721 1722 Describe("FindRouteBoundToSpaceWithSettings", func() { 1723 var ( 1724 route Route 1725 1726 returnedRoute Route 1727 warnings Warnings 1728 executeErr error 1729 ) 1730 1731 BeforeEach(func() { 1732 route = Route{ 1733 Domain: Domain{ 1734 Name: "some-domain.com", 1735 GUID: "some-domain-guid", 1736 }, 1737 Host: "some-host", 1738 Path: "some-path", 1739 SpaceGUID: "some-space-guid", 1740 } 1741 }) 1742 1743 JustBeforeEach(func() { 1744 returnedRoute, warnings, executeErr = actor.FindRouteBoundToSpaceWithSettings(route) 1745 }) 1746 1747 When("the route exists in the current space", func() { 1748 var existingRoute Route 1749 1750 When("the route uses an HTTP domain", func() { 1751 BeforeEach(func() { 1752 existingRoute = route 1753 existingRoute.GUID = "some-route-guid" 1754 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ActorToCCRoute(existingRoute)}, ccv2.Warnings{"get route warning"}, nil) 1755 }) 1756 1757 It("returns the route", func() { 1758 Expect(executeErr).ToNot(HaveOccurred()) 1759 Expect(returnedRoute).To(Equal(existingRoute)) 1760 Expect(warnings).To(ConsistOf("get route warning")) 1761 }) 1762 }) 1763 }) 1764 1765 When("the route exists in a different space", func() { 1766 When("the user has access to the route", func() { 1767 BeforeEach(func() { 1768 existingRoute := route 1769 existingRoute.GUID = "some-route-guid" 1770 existingRoute.SpaceGUID = "some-other-space-guid" 1771 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{ActorToCCRoute(existingRoute)}, ccv2.Warnings{"get route warning"}, nil) 1772 }) 1773 1774 It("returns a RouteInDifferentSpaceError", func() { 1775 Expect(executeErr).To(MatchError(actionerror.RouteInDifferentSpaceError{Route: route.String()})) 1776 Expect(warnings).To(ConsistOf("get route warning")) 1777 }) 1778 }) 1779 1780 When("the user does not have access to the route", func() { 1781 BeforeEach(func() { 1782 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get route warning"}, nil) 1783 fakeCloudControllerClient.CheckRouteReturns(true, ccv2.Warnings{"check route warning"}, nil) 1784 }) 1785 1786 It("returns a RouteInDifferentSpaceError", func() { 1787 Expect(executeErr).To(MatchError(actionerror.RouteInDifferentSpaceError{Route: route.String()})) 1788 Expect(warnings).To(ConsistOf("get route warning", "check route warning")) 1789 }) 1790 }) 1791 }) 1792 1793 When("the route does not exist", func() { 1794 var expectedErr error 1795 1796 BeforeEach(func() { 1797 expectedErr = actionerror.RouteNotFoundError{Host: route.Host, DomainGUID: route.Domain.GUID, Path: route.Path} 1798 fakeCloudControllerClient.GetRoutesReturns([]ccv2.Route{}, ccv2.Warnings{"get route warning"}, nil) 1799 fakeCloudControllerClient.CheckRouteReturns(false, ccv2.Warnings{"check route warning"}, nil) 1800 }) 1801 1802 It("returns the route", func() { 1803 Expect(executeErr).To(MatchError(expectedErr)) 1804 Expect(warnings).To(ConsistOf("get route warning", "check route warning")) 1805 }) 1806 }) 1807 1808 When("finding the route errors", func() { 1809 var expectedErr error 1810 1811 BeforeEach(func() { 1812 expectedErr = errors.New("booo") 1813 fakeCloudControllerClient.GetRoutesReturns(nil, ccv2.Warnings{"get route warning"}, expectedErr) 1814 }) 1815 1816 It("the error and warnings", func() { 1817 Expect(executeErr).To(MatchError(expectedErr)) 1818 Expect(warnings).To(ConsistOf("get route warning")) 1819 }) 1820 }) 1821 }) 1822 })