github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/integration/isolated/create_route_command_test.go (about) 1 package isolated 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 8 "code.cloudfoundry.org/cli/integration/helpers" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 . "github.com/onsi/gomega/gbytes" 12 . "github.com/onsi/gomega/gexec" 13 . "github.com/onsi/gomega/ghttp" 14 ) 15 16 var _ = Describe("create-route command", func() { 17 Context("Help", func() { 18 It("displays the help information", func() { 19 session := helpers.CF("create-route", "--help") 20 Eventually(session).Should(Say(`NAME:`)) 21 Eventually(session).Should(Say(`create-route - Create a url route in a space for later use\n`)) 22 Eventually(session).Should(Say(`\n`)) 23 24 Eventually(session).Should(Say(`USAGE:`)) 25 Eventually(session).Should(Say(`Create an HTTP route:`)) 26 Eventually(session).Should(Say(`cf create-route SPACE DOMAIN \[--hostname HOSTNAME\] \[--path PATH\]\n`)) 27 Eventually(session).Should(Say(`\n`)) 28 29 Eventually(session).Should(Say(`Create a TCP route:`)) 30 Eventually(session).Should(Say(`cf create-route SPACE DOMAIN \(--port PORT \| --random-port\)\n`)) 31 Eventually(session).Should(Say(`\n`)) 32 33 Eventually(session).Should(Say(`EXAMPLES:`)) 34 Eventually(session).Should(Say(`cf create-route my-space example.com\s+# example.com`)) 35 Eventually(session).Should(Say(`cf create-route my-space example.com --hostname myapp\s+# myapp.example.com`)) 36 Eventually(session).Should(Say(`cf create-route my-space example.com --hostname myapp --path foo\s+# myapp.example.com/foo`)) 37 Eventually(session).Should(Say(`cf create-route my-space example.com --port 5000\s+# example.com:5000\n`)) 38 Eventually(session).Should(Say(`\n`)) 39 40 Eventually(session).Should(Say(`OPTIONS:`)) 41 Eventually(session).Should(Say(`--hostname, -n\s+Hostname for the HTTP route \(required for shared domains\)`)) 42 Eventually(session).Should(Say(`--path\s+Path for the HTTP route`)) 43 Eventually(session).Should(Say(`--port\s+Port for the TCP route`)) 44 Eventually(session).Should(Say(`--random-port\s+Create a random port for the TCP route\n`)) 45 Eventually(session).Should(Say(`\n`)) 46 47 Eventually(session).Should(Say(`SEE ALSO:`)) 48 Eventually(session).Should(Say(`check-route, domains, map-route`)) 49 50 Eventually(session).Should(Exit(0)) 51 }) 52 }) 53 54 Context("Flag Errors", func() { 55 Context("when --hostname and --port are provided", func() { 56 It("fails with a message about being unable to mix --port with the HTTP route options", func() { 57 session := helpers.CF("create-route", "some-space", "some-domain", "--hostname", "some-host", "--port", "1122") 58 Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --hostname, --port`)) 59 Eventually(session).Should(Exit(1)) 60 }) 61 }) 62 63 Context("when --hostname and --random-port are provided", func() { 64 It("fails with a message about being unable to mix --random-port with any other options", func() { 65 session := helpers.CF("create-route", "some-space", "some-domain", "--hostname", "some-host", "--random-port") 66 Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --hostname, --random-port`)) 67 Eventually(session).Should(Exit(1)) 68 }) 69 }) 70 71 Context("when --path and --port are provided", func() { 72 It("fails with a message about being unable to mix --port with the HTTP route options", func() { 73 session := helpers.CF("create-route", "some-space", "some-domain", "--path", "/some-path", "--port", "1111") 74 Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --path, --port`)) 75 Eventually(session).Should(Exit(1)) 76 }) 77 }) 78 79 Context("when --path and --random-port are provided", func() { 80 It("fails with a message about being unable to mix --random-port with any other options", func() { 81 session := helpers.CF("create-route", "some-space", "some-domain", "--path", "/some-path", "--random-port") 82 Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --path, --random-port`)) 83 Eventually(session).Should(Exit(1)) 84 }) 85 }) 86 87 Context("when both --port and --random-port are provided", func() { 88 It("fails with a message about being unable to mix --random-port with any other options", func() { 89 session := helpers.CF("create-route", "some-space", "some-domain", "--port", "1121", "--random-port") 90 Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --port, --random-port`)) 91 Eventually(session).Should(Exit(1)) 92 }) 93 }) 94 95 Context("when the provided port is not valid / parseable", func() { 96 It("fails with an appropriate error", func() { 97 session := helpers.CF("create-route", "some-space", "some-domain", "--port", "ABC") 98 Eventually(session.Err).Should(Say(`Incorrect Usage: invalid argument for flag '--port' \(expected int > 0\)`)) 99 Eventually(session).Should(Exit(1)) 100 }) 101 }) 102 }) 103 104 Context("when the environment is not setup correctly", func() { 105 Context("when no API endpoint is set", func() { 106 BeforeEach(func() { 107 helpers.UnsetAPI() 108 }) 109 110 It("fails with no API endpoint set message", func() { 111 session := helpers.CF("create-route", "some-space", "some-domain") 112 Eventually(session).Should(Say(`FAILED`)) 113 Eventually(session.Err).Should(Say(`No API endpoint set\. Use 'cf login' or 'cf api' to target an endpoint\.`)) 114 Eventually(session).Should(Exit(1)) 115 }) 116 }) 117 118 Context("when not logged in", func() { 119 BeforeEach(func() { 120 helpers.LogoutCF() 121 }) 122 123 It("fails with not logged in message", func() { 124 session := helpers.CF("create-route", "some-space", "some-domain") 125 Eventually(session).Should(Say(`FAILED`)) 126 Eventually(session.Err).Should(Say(`Not logged in\. Use 'cf login' to log in\.`)) 127 Eventually(session).Should(Exit(1)) 128 }) 129 }) 130 131 Context("when no organization is targeted", func() { 132 BeforeEach(func() { 133 helpers.ClearTarget() 134 }) 135 136 It("fails with 'no organization targeted' message and exits 1", func() { 137 session := helpers.CF("create-route", "some-space", "some-domain") 138 Eventually(session).Should(Say(`FAILED`)) 139 Eventually(session.Err).Should(Say(`No org targeted, use 'cf target -o ORG' to target an org\.`)) 140 Eventually(session).Should(Exit(1)) 141 }) 142 }) 143 }) 144 145 Context("when the server's API version is too low", func() { 146 var server *Server 147 148 BeforeEach(func() { 149 server = NewTLSServer() 150 server.AppendHandlers( 151 CombineHandlers( 152 VerifyRequest(http.MethodGet, "/v2/info"), 153 RespondWith(http.StatusOK, `{"api_version":"2.34.0"}`), 154 ), 155 CombineHandlers( 156 VerifyRequest(http.MethodGet, "/v2/info"), 157 RespondWith(http.StatusOK, fmt.Sprintf(`{"api_version":"2.34.0", "authorization_endpoint": "%s"}`, server.URL())), 158 ), 159 CombineHandlers( 160 VerifyRequest(http.MethodGet, "/login"), 161 RespondWith(http.StatusOK, `{}`), 162 ), 163 ) 164 Eventually(helpers.CF("api", server.URL(), "--skip-ssl-validation")).Should(Exit(0)) 165 }) 166 167 AfterEach(func() { 168 server.Close() 169 }) 170 171 Context("for HTTP routes", func() { 172 Context("when specifying --path", func() { 173 It("reports an error with a minimum-version message", func() { 174 session := helpers.CF("create-route", "some-space", "example.com", "--path", "/foo") 175 Eventually(session).Should(Say(`FAILED`)) 176 Eventually(session.Err).Should(Say(`Option '--path' requires CF API version 2\.36\.0 or higher. Your target is 2\.34\.0\.`)) 177 Eventually(session).Should(Exit(1)) 178 }) 179 }) 180 }) 181 182 Context("for TCP routes", func() { 183 Context("when specifying --port", func() { 184 It("reports an error with a minimum-version message", func() { 185 session := helpers.CF("create-route", "some-space", "example.com", "--port", "1025") 186 Eventually(session).Should(Say(`FAILED`)) 187 Eventually(session.Err).Should(Say(`Option '--port' requires CF API version 2\.53\.0 or higher\. Your target is 2\.34\.0\.`)) 188 Eventually(session).Should(Exit(1)) 189 }) 190 }) 191 192 Context("when specifying --random-port", func() { 193 It("reports an error with a minimum-version message", func() { 194 session := helpers.CF("create-route", "some-space", "example.com", "--random-port") 195 Eventually(session).Should(Say(`FAILED`)) 196 Eventually(session.Err).Should(Say(`Option '--random-port' requires CF API version 2\.53\.0 or higher\. Your target is 2\.34\.0\.`)) 197 Eventually(session).Should(Exit(1)) 198 }) 199 }) 200 }) 201 }) 202 203 Context("when the environment is set up correctly", func() { 204 var ( 205 orgName string 206 spaceName string 207 ) 208 209 BeforeEach(func() { 210 orgName = helpers.NewOrgName() 211 spaceName = helpers.NewSpaceName() 212 213 helpers.SetupCF(orgName, spaceName) 214 }) 215 216 AfterEach(func() { 217 helpers.QuickDeleteOrg(orgName) 218 }) 219 220 Context("when the space does not exist", func() { 221 It("displays 'space not found' and exits 1", func() { 222 badSpaceName := fmt.Sprintf("%s-1", spaceName) 223 session := helpers.CF("create-route", badSpaceName, "some-domain") 224 Eventually(session).Should(Say(`FAILED`)) 225 Eventually(session.Err).Should(Say(`Space '%s' not found\.`, badSpaceName)) 226 Eventually(session).Should(Exit(1)) 227 }) 228 }) 229 230 Context("when the space is not specified", func() { 231 It("displays error and exits 1", func() { 232 session := helpers.CF("create-route") 233 Eventually(session.Err).Should(Say("Incorrect Usage: the required arguments `SPACE` and `DOMAIN` were not provided\n")) 234 Eventually(session.Err).Should(Say("\n")) 235 Eventually(session).Should(Say("NAME:\n")) 236 Eventually(session).Should(Exit(1)) 237 }) 238 }) 239 240 Context("when the domain does not exist", func() { 241 It("displays error and exits 1", func() { 242 session := helpers.CF("create-route", spaceName, "some-domain") 243 Eventually(session).Should(Say(`FAILED`)) 244 Eventually(session.Err).Should(Say(`Domain some-domain not found`)) 245 Eventually(session).Should(Exit(1)) 246 }) 247 }) 248 249 Context("when the domain is not specified", func() { 250 It("displays error and exits 1", func() { 251 session := helpers.CF("create-route", spaceName) 252 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `DOMAIN` was not provided\n")) 253 Eventually(session.Err).Should(Say("\n")) 254 Eventually(session).Should(Say("NAME:\n")) 255 Eventually(session).Should(Exit(1)) 256 }) 257 }) 258 259 Context("when the space and domain exist", func() { 260 var ( 261 userName string 262 domainName string 263 ) 264 265 BeforeEach(func() { 266 domainName = helpers.DomainName() 267 userName, _ = helpers.GetCredentials() 268 }) 269 270 Context("when the route already exists", func() { 271 var domain helpers.Domain 272 273 BeforeEach(func() { 274 domain = helpers.NewDomain(orgName, domainName) 275 domain.Create() 276 Eventually(helpers.CF("create-route", spaceName, domainName)).Should(Exit(0)) 277 }) 278 279 AfterEach(func() { 280 domain.Delete() 281 }) 282 283 It("warns the user that it has already been created and runs to completion without failing", func() { 284 session := helpers.CF("create-route", spaceName, domainName) 285 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 286 Eventually(session.Err).Should(Say(`Route %s already exists\.`, domainName)) 287 Eventually(session).Should(Say(`OK`)) 288 Eventually(session).Should(Exit(0)) 289 }) 290 }) 291 292 Context("when the route already exists in a different space", func() { 293 var domain helpers.Domain 294 295 BeforeEach(func() { 296 domain = helpers.NewDomain(orgName, domainName) 297 domain.Create() 298 differentSpaceName := helpers.NewSpaceName() 299 helpers.CreateSpace(differentSpaceName) 300 Eventually(helpers.CF("create-route", differentSpaceName, domainName)).Should(Exit(0)) 301 }) 302 303 AfterEach(func() { 304 domain.Delete() 305 }) 306 307 It("warns the user that the route is already in use and then fails", func() { 308 session := helpers.CF("create-route", spaceName, domainName) 309 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 310 Eventually(session.Err).Should(Say("The app cannot be mapped to route %s because the route exists in a different space.", domainName)) 311 Eventually(session).Should(Say(`FAILED`)) 312 Eventually(session).Should(Exit(1)) 313 }) 314 }) 315 316 Context("when the route does not already exist", func() { 317 Context("when the domain is private", func() { 318 var domain helpers.Domain 319 320 BeforeEach(func() { 321 domain = helpers.NewDomain(orgName, domainName) 322 domain.Create() 323 Eventually(helpers.CF("create-route", spaceName, domainName)).Should(Exit(0)) 324 }) 325 326 AfterEach(func() { 327 domain.Delete() 328 }) 329 330 Context("when no flags are used", func() { 331 It("creates the route", func() { 332 session := helpers.CF("create-route", spaceName, domainName) 333 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 334 Eventually(session).Should(Exit(0)) 335 }) 336 }) 337 338 Context("when the path is provided but the hostname is not", func() { 339 var path string 340 341 BeforeEach(func() { 342 path = helpers.PrefixedRandomName("path") 343 }) 344 345 It("creates the route", func() { 346 session := helpers.CF("create-route", spaceName, domainName, "--path", path) 347 Eventually(session).Should(Say(`Creating route %s/%s for org %s / space %s as %s\.\.\.`, domainName, path, orgName, spaceName, userName)) 348 Eventually(session).Should(Exit(0)) 349 }) 350 }) 351 }) 352 353 Context("when the domain is a shared HTTP domain", func() { 354 var domain helpers.Domain 355 356 BeforeEach(func() { 357 domain = helpers.NewDomain(orgName, domainName) 358 domain.CreateShared() 359 }) 360 361 AfterEach(func() { 362 domain.DeleteShared() 363 }) 364 365 Context("when no flags are used", func() { 366 Context("when the domain already has some routes", func() { 367 var hostName string 368 369 BeforeEach(func() { 370 hostName = helpers.PrefixedRandomName("my-host") 371 Eventually(helpers.CF("create-route", spaceName, domainName, "--hostname", hostName)).Should(Exit(0)) 372 }) 373 374 It("fails with error message informing users to provide a port or random-port", func() { 375 session := helpers.CF("create-route", spaceName, domainName) 376 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 377 Eventually(session).Should(Say(`FAILED`)) 378 Eventually(session.Err).Should(Say(`The route is invalid: host is required for shared-domains`)) 379 Eventually(session).Should(Exit(1)) 380 }) 381 }) 382 383 It("fails with an error message and exits 1", func() { 384 session := helpers.CF("create-route", spaceName, domainName) 385 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 386 Eventually(session.Err).Should(Say(`The route is invalid: host is required for shared-domains`)) 387 Eventually(session).Should(Exit(1)) 388 }) 389 }) 390 391 Context("when TCP flag options are provided", func() { 392 It("fails with an error message and exits 1", func() { 393 port := "90230" 394 session := helpers.CF("create-route", spaceName, domainName, "--port", port) 395 Eventually(session).Should(Say(`Creating route %s:%s for org %s / space %s as %s\.\.\.`, domainName, port, orgName, spaceName, userName)) 396 Eventually(session.Err).Should(Say(`Port not allowed in HTTP domain %s`, domainName)) 397 Eventually(session).Should(Exit(1)) 398 }) 399 400 It("fails with an error message and exits 1", func() { 401 session := helpers.CF("create-route", spaceName, domainName, "--random-port") 402 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 403 Eventually(session.Err).Should(Say(`Port not allowed in HTTP domain %s`, domainName)) 404 Eventually(session).Should(Exit(1)) 405 }) 406 }) 407 408 Context("when the hostname is provided", func() { 409 var hostName string 410 411 BeforeEach(func() { 412 hostName = helpers.PrefixedRandomName("my-host") 413 }) 414 415 Context("when no path is provided", func() { 416 It("creates the route", func() { 417 session := helpers.CF("create-route", spaceName, domainName, "--hostname", hostName) 418 Eventually(session).Should(Say(`Creating route %s.%s for org %s / space %s as %s\.\.\.`, hostName, domainName, orgName, spaceName, userName)) 419 Eventually(session).Should(Exit(0)) 420 }) 421 }) 422 423 Context("when a path is provided", func() { 424 It("creates the route", func() { 425 path := fmt.Sprintf("/%s", helpers.PrefixedRandomName("path")) 426 session := helpers.CF("create-route", spaceName, domainName, "--hostname", hostName, "--path", path) 427 Eventually(session).Should(Say(`Creating route %s.%s%s for org %s / space %s as %s\.\.\.`, hostName, domainName, path, orgName, spaceName, userName)) 428 Eventually(session).Should(Exit(0)) 429 }) 430 }) 431 }) 432 433 Context("when the hostname is not provided", func() { 434 var path string 435 436 BeforeEach(func() { 437 path = helpers.PrefixedRandomName("path") 438 }) 439 440 Context("when the path is provided", func() { 441 It("fails with an error message and exits 1", func() { 442 session := helpers.CF("create-route", spaceName, domainName, "-v", "--path", path) 443 Eventually(session).Should(Say(`Creating route %s/%s for org %s / space %s as %s\.\.\.`, domainName, path, orgName, spaceName, userName)) 444 Eventually(session.Err).Should(Say(`The route is invalid: host is required for shared-domains`)) 445 Eventually(session).Should(Exit(1)) 446 }) 447 }) 448 }) 449 }) 450 451 Context("when the domain is a shared TCP domain", func() { 452 var domain helpers.Domain 453 454 BeforeEach(func() { 455 helpers.SkipIfVersionLessThan(ccversion.MinVersionRoutingV3) 456 domain = helpers.NewDomain(orgName, domainName) 457 domain.CreateWithRouterGroup(helpers.FindOrCreateTCPRouterGroup(GinkgoParallelNode())) 458 }) 459 460 AfterEach(func() { 461 domain.DeleteShared() 462 }) 463 464 Context("when HTTP flag options are provided", func() { 465 It("fails with an error message and exits 1", func() { 466 hostName := helpers.PrefixedRandomName("host-") 467 path := helpers.PrefixedRandomName("path-") 468 session := helpers.CF("create-route", spaceName, domainName, "--hostname", hostName, "--path", path) 469 Eventually(session).Should(Say(`Creating route %s.%s/%s for org %s / space %s as %s\.\.\.`, hostName, domainName, path, orgName, spaceName, userName)) 470 Eventually(session.Err).Should(Say(`The route is invalid: For TCP routes you must specify a port or request a random one.`)) 471 Eventually(session).Should(Exit(1)) 472 }) 473 }) 474 475 Context("when a port is provided", func() { 476 It("creates the route", func() { 477 port := "1025" 478 session := helpers.CF("create-route", spaceName, domainName, "--port", port) 479 Eventually(session).Should(Say(`Creating route %s:%s for org %s / space %s as %s\.\.\.`, domainName, port, orgName, spaceName, userName)) 480 Eventually(session).Should(Exit(0)) 481 }) 482 }) 483 484 Context("when --random-port is provided", func() { 485 It("creates the route", func() { 486 session := helpers.CF("create-route", spaceName, domainName, "--random-port") 487 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 488 Eventually(session).Should(Say(`Route %s:\d+ has been created\.`, domainName)) 489 Eventually(session).Should(Exit(0)) 490 }) 491 492 Context("when there are other routes in the domain we want to create the route with", func() { 493 BeforeEach(func() { 494 session := helpers.CF("create-route", spaceName, domainName, "--random-port") 495 Eventually(session).Should(Say(`Route %s:\d+ has been created\.`, domainName)) 496 Eventually(session).Should(Exit(0)) 497 }) 498 499 It("should determine that the random route does not already exist, and create it", func() { 500 session := helpers.CF("create-route", spaceName, domainName, "--random-port") 501 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 502 Eventually(session).Should(Say(`Route %s:\d+ has been created\.`, domainName)) 503 Eventually(session).Should(Exit(0)) 504 }) 505 }) 506 }) 507 508 Context("when no options are provided", func() { 509 It("fails with error message informing users to provide a port or random-port", func() { 510 session := helpers.CF("create-route", spaceName, domainName) 511 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 512 Eventually(session).Should(Say(`FAILED`)) 513 Eventually(session.Err).Should(Say(`The route is invalid: For TCP routes you must specify a port or request a random one.`)) 514 Eventually(session).Should(Exit(1)) 515 }) 516 517 Context("when the domain already has some routes", func() { 518 BeforeEach(func() { 519 Eventually(helpers.CF("create-route", spaceName, domainName, "--random-port")).Should(Exit(0)) 520 }) 521 522 It("fails with error message informing users to provide a port or random-port", func() { 523 session := helpers.CF("create-route", spaceName, domainName) 524 Eventually(session).Should(Say(`Creating route %s for org %s / space %s as %s\.\.\.`, domainName, orgName, spaceName, userName)) 525 Eventually(session).Should(Say(`FAILED`)) 526 Eventually(session.Err).Should(Say(`The route is invalid: For TCP routes you must specify a port or request a random one.`)) 527 Eventually(session).Should(Exit(1)) 528 }) 529 }) 530 }) 531 }) 532 }) 533 }) 534 }) 535 })