github.com/loafoe/cli@v7.1.0+incompatible/integration/v6/push/combination_manifest_and_flag_test.go (about) 1 package push 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "regexp" 8 9 "code.cloudfoundry.org/cli/integration/helpers" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/ginkgo/extensions/table" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gbytes" 14 . "github.com/onsi/gomega/gexec" 15 ) 16 17 var _ = Describe("push with a simple manifest and flags", func() { 18 var ( 19 appName string 20 ) 21 22 BeforeEach(func() { 23 appName = helpers.NewAppName() 24 }) 25 26 When("the app is new", func() { 27 When("pushing a single app from the manifest", func() { 28 When("the '-f' flag is provided", func() { 29 var ( 30 pathToManifest string // Can be a filepath or a directory with a manifest. 31 ) 32 33 When("the manifest file is passed", func() { 34 BeforeEach(func() { 35 tmpFile, err := ioutil.TempFile("", "combination-manifest") 36 Expect(err).ToNot(HaveOccurred()) 37 pathToManifest = tmpFile.Name() 38 Expect(tmpFile.Close()).ToNot(HaveOccurred()) 39 }) 40 41 AfterEach(func() { 42 Expect(os.Remove(pathToManifest)).ToNot(HaveOccurred()) 43 }) 44 45 When("pushing the app from the current directory", func() { 46 BeforeEach(func() { 47 helpers.WriteManifest(pathToManifest, map[string]interface{}{ 48 "applications": []map[string]string{ 49 { 50 "name": appName, 51 }, 52 }, 53 }) 54 }) 55 56 It("pushes the app from the current directory and the manifest for app settings", func() { 57 helpers.WithHelloWorldApp(func(dir string) { 58 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-f", pathToManifest) 59 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 60 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 61 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 62 Eventually(session).Should(Say(`\s+routes:`)) 63 Eventually(session).Should(Say(`(?i)\+\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 64 Eventually(session).Should(Say(`Mapping routes\.\.\.`)) 65 Eventually(session).Should(Say(`Uploading files\.\.\.`)) 66 Eventually(session).Should(Say("100.00%")) 67 Eventually(session).Should(Say(`Waiting for API to complete processing files\.\.\.`)) 68 helpers.ConfirmStagingLogs(session) 69 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 70 Eventually(session).Should(Say(`requested state:\s+started`)) 71 Eventually(session).Should(Exit(0)) 72 }) 73 74 session := helpers.CF("app", appName) 75 Eventually(session).Should(Say(`name:\s+%s`, appName)) 76 Eventually(session).Should(Exit(0)) 77 }) 78 }) 79 80 When("the path to the application is provided in the manifest", func() { 81 It("pushes the app from the path specified in the manifest and uses the manifest for app settings", func() { 82 helpers.WithHelloWorldApp(func(dir string) { 83 helpers.WriteManifest(pathToManifest, map[string]interface{}{ 84 "applications": []map[string]string{ 85 { 86 "name": appName, 87 "path": filepath.Base(dir), 88 }, 89 }, 90 }) 91 92 session := helpers.CF(PushCommandName, "-f", pathToManifest) 93 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 94 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 95 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 96 Eventually(session).Should(helpers.SayPath(`\s+path:\s+%s`, dir)) 97 Eventually(session).Should(Say(`requested state:\s+started`)) 98 Eventually(session).Should(Exit(0)) 99 }) 100 101 session := helpers.CF("app", appName) 102 Eventually(session).Should(Say(`name:\s+%s`, appName)) 103 Eventually(session).Should(Exit(0)) 104 }) 105 }) 106 }) 107 108 When("a directory is passed", func() { 109 var ( 110 ymlFile string 111 yamlFile string 112 ) 113 114 BeforeEach(func() { 115 var err error 116 pathToManifest, err = ioutil.TempDir("", "manifest-integration-") 117 Expect(err).ToNot(HaveOccurred()) 118 }) 119 120 AfterEach(func() { 121 Expect(os.RemoveAll(pathToManifest)).ToNot(HaveOccurred()) 122 }) 123 124 When("the directory contains a 'manifest.yml' file", func() { 125 BeforeEach(func() { 126 ymlFile = filepath.Join(pathToManifest, "manifest.yml") 127 helpers.WriteManifest(ymlFile, map[string]interface{}{ 128 "applications": []map[string]interface{}{ 129 { 130 "name": appName, 131 "instances": 2, 132 }, 133 }, 134 }) 135 }) 136 137 It("pushes the app from the given directory and the found 'manifest.yml' for app settings", func() { 138 helpers.WithHelloWorldApp(func(dir string) { 139 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-f", pathToManifest, "--no-start") 140 Eventually(session).Should(Say("Using manifest file %s", regexp.QuoteMeta(ymlFile))) 141 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 142 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 143 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 144 Eventually(session).Should(Say(`\+\s+instances:\s+%d`, 2)) 145 Eventually(session).Should(Say(`\s+routes:`)) 146 Eventually(session).Should(Say(`(?i)\+\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 147 Eventually(session).Should(Say(`Mapping routes\.\.\.`)) 148 Eventually(session).Should(Say(`Uploading files\.\.\.`)) 149 Eventually(session).Should(Say("100.00%")) 150 Eventually(session).Should(Say(`Waiting for API to complete processing files\.\.\.`)) 151 Eventually(session).Should(Exit(0)) 152 }) 153 154 session := helpers.CF("app", appName) 155 Eventually(session).Should(Say(`name:\s+%s`, appName)) 156 Eventually(session).Should(Exit(0)) 157 }) 158 }) 159 When("the directory contains a 'manifest.yaml' file", func() { 160 BeforeEach(func() { 161 yamlFile = filepath.Join(pathToManifest, "manifest.yaml") 162 helpers.WriteManifest(yamlFile, map[string]interface{}{ 163 "applications": []map[string]interface{}{ 164 { 165 "name": appName, 166 "instances": 2, 167 }, 168 }, 169 }) 170 }) 171 172 It("pushes the app from the given directory and the found 'manifest.yaml' for app settings", func() { 173 helpers.WithHelloWorldApp(func(dir string) { 174 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-f", pathToManifest, "--no-start") 175 Eventually(session).Should(Say("Using manifest file %s", regexp.QuoteMeta(yamlFile))) 176 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 177 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 178 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 179 Eventually(session).Should(Say(`\+\s+instances:\s+%d`, 2)) 180 Eventually(session).Should(Say(`\s+routes:`)) 181 Eventually(session).Should(Say(`(?i)\+\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 182 Eventually(session).Should(Say(`Mapping routes\.\.\.`)) 183 Eventually(session).Should(Say(`Uploading files\.\.\.`)) 184 Eventually(session).Should(Say("100.00%")) 185 Eventually(session).Should(Say(`Waiting for API to complete processing files\.\.\.`)) 186 Eventually(session).Should(Exit(0)) 187 }) 188 189 session := helpers.CF("app", appName) 190 Eventually(session).Should(Say(`name:\s+%s`, appName)) 191 Eventually(session).Should(Exit(0)) 192 }) 193 }) 194 195 When("the directory contains both a 'manifest.yml' file and a 'manifest.yaml' file", func() { 196 BeforeEach(func() { 197 ymlFile = filepath.Join(pathToManifest, "manifest.yml") 198 helpers.WriteManifest(ymlFile, map[string]interface{}{ 199 "applications": []map[string]interface{}{ 200 { 201 "name": appName, 202 "instances": 2, 203 }, 204 }, 205 }) 206 207 yamlFile = filepath.Join(pathToManifest, "manifest.yaml") 208 helpers.WriteManifest(yamlFile, map[string]interface{}{ 209 "applications": []map[string]interface{}{ 210 { 211 "name": appName, 212 "instances": 4, 213 }, 214 }, 215 }) 216 }) 217 218 It("pushes the app from the given directory and the found 'manifest.yml' for app settings", func() { 219 helpers.WithHelloWorldApp(func(dir string) { 220 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-f", pathToManifest, "--no-start") 221 Eventually(session).Should(Say("Using manifest file %s", regexp.QuoteMeta(ymlFile))) 222 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 223 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 224 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 225 Eventually(session).Should(Say(`\+\s+instances:\s+%d`, 2)) 226 Eventually(session).Should(Say(`\s+routes:`)) 227 Eventually(session).Should(Say(`(?i)\+\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 228 Eventually(session).Should(Say(`Mapping routes\.\.\.`)) 229 Eventually(session).Should(Say(`Uploading files\.\.\.`)) 230 Eventually(session).Should(Say("100.00%")) 231 Eventually(session).Should(Say(`Waiting for API to complete processing files\.\.\.`)) 232 Eventually(session).Should(Exit(0)) 233 }) 234 235 session := helpers.CF("app", appName) 236 Eventually(session).Should(Say(`name:\s+%s`, appName)) 237 Eventually(session).Should(Exit(0)) 238 }) 239 }) 240 241 When("the directory contains no manifest file", func() { 242 It("returns a no manifest file error", func() { 243 helpers.WithHelloWorldApp(func(dir string) { 244 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-f", pathToManifest, "--no-start") 245 Eventually(session.Err).Should(Say(`Could not find 'manifest\.yml' file in %s`, regexp.QuoteMeta(pathToManifest))) 246 Eventually(session).Should(Say("FAILED")) 247 Eventually(session).Should(Exit(1)) 248 }) 249 }) 250 251 }) 252 }) 253 }) 254 255 Context("manifest contains a path and a '-p' is provided", func() { 256 var tempDir string 257 258 BeforeEach(func() { 259 var err error 260 tempDir, err = ioutil.TempDir("", "combination-manifest-with-p") 261 Expect(err).ToNot(HaveOccurred()) 262 263 helpers.WriteManifest(filepath.Join(tempDir, "manifest.yml"), map[string]interface{}{ 264 "applications": []map[string]string{ 265 { 266 "name": appName, 267 "path": "does-not-exist", 268 }, 269 }, 270 }) 271 }) 272 273 AfterEach(func() { 274 Expect(os.RemoveAll(tempDir)).To(Succeed()) 275 }) 276 277 It("overrides the manifest path with the '-p' path", func() { 278 helpers.WithHelloWorldApp(func(dir string) { 279 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, PushCommandName, "-p", dir) 280 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 281 Eventually(session).Should(helpers.SayPath(`\s+path:\s+%s`, dir)) 282 Eventually(session).Should(Say(`requested state:\s+started`)) 283 Eventually(session).Should(Exit(0)) 284 }) 285 286 session := helpers.CF("app", appName) 287 Eventually(session).Should(Say(`name:\s+%s`, appName)) 288 Eventually(session).Should(Exit(0)) 289 }) 290 }) 291 292 Context("manifest contains a name and a name is provided", func() { 293 It("overrides the manifest name", func() { 294 helpers.WithHelloWorldApp(func(dir string) { 295 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 296 "applications": []map[string]string{ 297 { 298 "name": "earle", 299 }, 300 }, 301 }) 302 303 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName) 304 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 305 Eventually(session).Should(Say(`requested state:\s+started`)) 306 Eventually(session).Should(Exit(0)) 307 }) 308 309 session := helpers.CF("app", appName) 310 Eventually(session).Should(Say(`name:\s+%s`, appName)) 311 Eventually(session).Should(Exit(0)) 312 }) 313 }) 314 315 When("the --no-manifest flag is passed", func() { 316 It("does not use the provided manifest", func() { 317 helpers.WithHelloWorldApp(func(dir string) { 318 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 319 "applications": []map[string]string{ 320 { 321 "name": "crazy-jerry", 322 }, 323 }, 324 }) 325 326 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "--no-manifest", appName) 327 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 328 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 329 Eventually(session).Should(Say(`\+\s+name:\s+%s`, appName)) 330 Eventually(session).Should(Say(`\s+routes:`)) 331 Eventually(session).Should(Say(`(?i)\+\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 332 Eventually(session).Should(Say(`Mapping routes\.\.\.`)) 333 Eventually(session).Should(Say(`Uploading files\.\.\.`)) 334 Eventually(session).Should(Say("100.00%")) 335 Eventually(session).Should(Say(`Waiting for API to complete processing files\.\.\.`)) 336 helpers.ConfirmStagingLogs(session) 337 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 338 Eventually(session).Should(Say(`requested state:\s+started`)) 339 Eventually(session).Should(Exit(0)) 340 }) 341 342 session := helpers.CF("app", appName) 343 Eventually(session).Should(Say(`name:\s+%s`, appName)) 344 Eventually(session).Should(Exit(0)) 345 }) 346 }) 347 348 When("the manifest contains 'routes'", func() { 349 var manifestContents map[string]interface{} 350 351 BeforeEach(func() { 352 manifestContents = map[string]interface{}{ 353 "applications": []map[string]interface{}{ 354 { 355 "name": appName, 356 "routes": []map[string]string{ 357 {"route": "some-route-1"}, 358 {"route": "some-route-2"}, 359 }, 360 }, 361 }, 362 } 363 }) 364 365 When("the -d flag is provided", func() { 366 It("returns an error message and exits 1", func() { 367 helpers.WithHelloWorldApp(func(dir string) { 368 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifestContents) 369 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-d", "some-domain.com") 370 371 Eventually(session).ShouldNot(Say("Getting app info")) 372 Eventually(session.Err).Should(Say("The following arguments cannot be used with an app manifest that declares routes using the 'route' attribute: -d, --hostname, -n, --no-hostname, --route-path")) 373 Eventually(session).Should(Exit(1)) 374 }) 375 }) 376 }) 377 378 When("the --hostname flag is provided", func() { 379 It("returns an error message and exits 1", func() { 380 helpers.WithHelloWorldApp(func(dir string) { 381 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifestContents) 382 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "--hostname", "some-host") 383 384 Eventually(session).ShouldNot(Say("Getting app info")) 385 Eventually(session.Err).Should(Say("The following arguments cannot be used with an app manifest that declares routes using the 'route' attribute: -d, --hostname, -n, --no-hostname, --route-path")) 386 Eventually(session).Should(Exit(1)) 387 }) 388 }) 389 }) 390 391 When("the -n flag is provided", func() { 392 It("returns an error message and exits 1", func() { 393 helpers.WithHelloWorldApp(func(dir string) { 394 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifestContents) 395 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "-n", "some-host") 396 397 Eventually(session).ShouldNot(Say("Getting app info")) 398 Eventually(session.Err).Should(Say("The following arguments cannot be used with an app manifest that declares routes using the 'route' attribute: -d, --hostname, -n, --no-hostname, --route-path")) 399 Eventually(session).Should(Exit(1)) 400 }) 401 }) 402 }) 403 404 When("the --no-hostname flag is provided", func() { 405 It("returns an error message and exits 1", func() { 406 helpers.WithHelloWorldApp(func(dir string) { 407 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifestContents) 408 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "--no-hostname") 409 410 Eventually(session).ShouldNot(Say("Getting app info")) 411 Eventually(session.Err).Should(Say("The following arguments cannot be used with an app manifest that declares routes using the 'route' attribute: -d, --hostname, -n, --no-hostname, --route-path")) 412 Eventually(session).Should(Exit(1)) 413 }) 414 }) 415 }) 416 417 When("the --route-path flag is provided", func() { 418 It("returns an error message and exits 1", func() { 419 helpers.WithHelloWorldApp(func(dir string) { 420 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifestContents) 421 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "--route-path", "some-path") 422 423 Eventually(session).ShouldNot(Say("Getting app info")) 424 Eventually(session.Err).Should(Say("The following arguments cannot be used with an app manifest that declares routes using the 'route' attribute: -d, --hostname, -n, --no-hostname, --route-path")) 425 Eventually(session).Should(Exit(1)) 426 }) 427 }) 428 }) 429 }) 430 }) 431 432 When("pushing multiple apps from the manifest", func() { 433 Context("manifest contains multiple apps and '--no-start' is provided", func() { 434 var appName1, appName2 string 435 436 BeforeEach(func() { 437 appName1 = helpers.NewAppName() 438 appName2 = helpers.NewAppName() 439 }) 440 441 It("does not start the apps", func() { 442 helpers.WithHelloWorldApp(func(dir string) { 443 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 444 "applications": []map[string]string{ 445 {"name": appName1}, 446 {"name": appName2}, 447 }, 448 }) 449 450 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, "--no-start") 451 Eventually(session).Should(Say(`Getting app info\.\.\.`)) 452 Eventually(session).Should(Say(`Creating app with these attributes\.\.\.`)) 453 Eventually(session).Should(Say(`\s+name:\s+%s`, appName1)) 454 Eventually(session).Should(Say(`requested state:\s+stopped`)) 455 Eventually(session).Should(Say(`\s+name:\s+%s`, appName2)) 456 Eventually(session).Should(Say(`requested state:\s+stopped`)) 457 Eventually(session).Should(Exit(0)) 458 }) 459 }) 460 }) 461 462 Context("manifest contains multiple apps and a '-p' is provided", func() { 463 var tempDir string 464 465 BeforeEach(func() { 466 var err error 467 tempDir, err = ioutil.TempDir("", "combination-manifest-with-p") 468 Expect(err).ToNot(HaveOccurred()) 469 470 helpers.WriteManifest(filepath.Join(tempDir, "manifest.yml"), map[string]interface{}{ 471 "applications": []map[string]string{ 472 { 473 "name": "name-1", 474 }, 475 { 476 "name": "name-2", 477 }, 478 }, 479 }) 480 }) 481 482 AfterEach(func() { 483 Expect(os.RemoveAll(tempDir)).ToNot(HaveOccurred()) 484 }) 485 486 It("returns an error", func() { 487 helpers.WithHelloWorldApp(func(dir string) { 488 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, PushCommandName, "-p", dir) 489 Eventually(session.Err).Should(Say(regexp.QuoteMeta("Incorrect Usage: Command line flags (except -f and --no-start) cannot be applied when pushing multiple apps from a manifest file."))) 490 Eventually(session).Should(Exit(1)) 491 }) 492 }) 493 }) 494 495 DescribeTable("errors when any flag (except for -f and --no-start) is specified", 496 func(flags ...string) { 497 helpers.WithHelloWorldApp(func(dir string) { 498 helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), map[string]interface{}{ 499 "applications": []map[string]string{ 500 {"name": "some-app"}, 501 {"name": "some-other-app"}, 502 }, 503 }) 504 505 args := append([]string{PushCommandName}, flags...) 506 session := helpers.CustomCF(helpers.CFEnv{ 507 WorkingDirectory: dir, 508 EnvVars: map[string]string{"CF_DOCKER_PASSWORD": "some-password"}, 509 }, args...) 510 Eventually(session.Err).Should(Say(regexp.QuoteMeta("Incorrect Usage: Command line flags (except -f and --no-start) cannot be applied when pushing multiple apps from a manifest file."))) 511 Eventually(session).Should(Exit(1)) 512 }) 513 }, 514 Entry("buildpack", "-b", "somethin"), 515 Entry("domain", "-d", "something"), 516 Entry("hostname", "-n", "something"), 517 Entry("quota", "-k", "100M"), 518 Entry("docker image", "-o", "something"), 519 Entry("docker image and username", "-o", "something", "--docker-username", "something"), 520 Entry("health check timeout", "-t", "10"), 521 Entry("health check type", "-u", "http"), 522 Entry("instances", "-i", "10"), 523 Entry("memory", "-m", "100M"), 524 Entry("no hostname", "--no-hostname"), 525 Entry("no route", "--no-route"), 526 Entry("random route", "--random-route"), 527 Entry("route path", "--route-path", "something"), 528 Entry("stack", "-s", "something"), 529 ) 530 }) 531 }) 532 })